mirror of
https://github.com/wekan/wekan.git
synced 2025-04-23 13:37:09 -04:00
Merge branch 'search' into admin-reports
This commit is contained in:
commit
4de830d663
23 changed files with 231 additions and 195 deletions
|
@ -1,7 +1,7 @@
|
|||
template(name="commentForm")
|
||||
.new-comment.js-new-comment(
|
||||
class="{{#if commentFormIsOpen}}is-open{{/if}}")
|
||||
+userAvatar(userId=currentUser._id)
|
||||
+userAvatar(userId=currentUser._id noRemove=true)
|
||||
form.js-new-comment-form
|
||||
+editor(class="js-new-comment-input")
|
||||
| {{getUnsavedValue 'cardComment' currentCard._id}}
|
||||
|
|
|
@ -110,9 +110,18 @@ template(name="cardDetails")
|
|||
a.card-label.add-label.js-end-date
|
||||
i.fa.fa-plus
|
||||
|
||||
hr
|
||||
if currentBoard.allowsCreator
|
||||
.card-details-item.card-details-item-creator
|
||||
h3.card-details-item-title
|
||||
i.fa.fa-user
|
||||
| {{_ 'creator'}}
|
||||
|
||||
+userAvatar(userId=userId noRemove=true)
|
||||
| {{! XXX Hack to hide syntaxic coloration /// }}
|
||||
|
||||
//.card-details-items
|
||||
if currentBoard.allowsMembers
|
||||
hr
|
||||
.card-details-item.card-details-item-members
|
||||
h3.card-details-item-title
|
||||
i.fa.fa-users
|
||||
|
|
|
@ -356,7 +356,7 @@ BlazeComponent.extendComponent({
|
|||
'click .js-go-to-linked-card'() {
|
||||
Utils.goCardId(this.data().linkedId);
|
||||
},
|
||||
'click .js-member': Popup.open('cardMember'),
|
||||
// 'click .js-member': Popup.open('cardMember'),
|
||||
'click .js-add-members': Popup.open('cardMembers'),
|
||||
'click .js-assignee': Popup.open('cardAssignee'),
|
||||
'click .js-add-assignees': Popup.open('cardAssignees'),
|
||||
|
|
|
@ -211,6 +211,7 @@ avatar-radius = 50%
|
|||
word-wrap: break-word
|
||||
max-width: 36%
|
||||
flex-grow: 1
|
||||
&.card-details-item-creator,
|
||||
&.card-details-item-received,
|
||||
&.card-details-item-start,
|
||||
&.card-details-item-due,
|
||||
|
|
|
@ -96,6 +96,10 @@ template(name="minicard")
|
|||
each getMembers
|
||||
+userAvatar(userId=this)
|
||||
|
||||
if showCreator
|
||||
.minicard-creator
|
||||
+userAvatar(userId=this.userId noRemove=true)
|
||||
|
||||
.badges
|
||||
unless currentUser.isNoComments
|
||||
if comments.count
|
||||
|
|
|
@ -21,6 +21,18 @@ BlazeComponent.extendComponent({
|
|||
}).format(customFieldTrueValue);
|
||||
},
|
||||
|
||||
showCreator() {
|
||||
if (this.data().board()) {
|
||||
return (
|
||||
this.data().board.allowsCreator === null ||
|
||||
this.data().board().allowsCreator === undefined ||
|
||||
this.data().board().allowsCreator
|
||||
);
|
||||
// return this.data().board().allowsCreator;
|
||||
}
|
||||
return false;
|
||||
},
|
||||
|
||||
events() {
|
||||
return [
|
||||
{
|
||||
|
|
|
@ -89,7 +89,7 @@
|
|||
border-radius: 2px
|
||||
margin-right: 3px
|
||||
margin-bottom: 3px
|
||||
|
||||
|
||||
.minicard-custom-fields
|
||||
display:block;
|
||||
.minicard-custom-field
|
||||
|
@ -163,7 +163,8 @@
|
|||
line-height: 12px
|
||||
|
||||
.minicard-members,
|
||||
.minicard-assignees
|
||||
.minicard-assignees,
|
||||
.minicard-creator
|
||||
float: right
|
||||
margin-left: 5px
|
||||
margin-bottom: 4px
|
||||
|
@ -187,6 +188,9 @@
|
|||
.minicard-assignees
|
||||
border-bottom: 1px solid red
|
||||
|
||||
.minicard-creator
|
||||
border-bottom: 1px solid green
|
||||
|
||||
.minicard-members:empty,
|
||||
.minicard-assignees:empty
|
||||
display: none
|
||||
|
|
|
@ -50,8 +50,7 @@ template(name="globalSearch")
|
|||
each msg in errorMessages
|
||||
li.global-search-error-messages
|
||||
= msg
|
||||
else
|
||||
+resultsPaged(this)
|
||||
+resultsPaged(this)
|
||||
else if serverError.get
|
||||
.global-search-page
|
||||
.global-search-help
|
||||
|
|
|
@ -123,6 +123,7 @@ class GlobalSearchComponent extends CardSearchPagedComponent {
|
|||
operator_member_abbrev: TAPi18n.__('operator-member-abbrev'),
|
||||
operator_assignee: TAPi18n.__('operator-assignee'),
|
||||
operator_assignee_abbrev: TAPi18n.__('operator-assignee-abbrev'),
|
||||
operator_creator: TAPi18n.__('operator-creator'),
|
||||
operator_due: TAPi18n.__('operator-due'),
|
||||
operator_created: TAPi18n.__('operator-created'),
|
||||
operator_modified: TAPi18n.__('operator-modified'),
|
||||
|
@ -167,6 +168,7 @@ class GlobalSearchComponent extends CardSearchPagedComponent {
|
|||
['\n* ', 'globalSearch-instructions-operator-at'],
|
||||
['\n* ', 'globalSearch-instructions-operator-member'],
|
||||
['\n* ', 'globalSearch-instructions-operator-assignee'],
|
||||
['\n* ', 'globalSearch-instructions-operator-creator'],
|
||||
['\n* ', 'globalSearch-instructions-operator-due'],
|
||||
['\n* ', 'globalSearch-instructions-operator-created'],
|
||||
['\n* ', 'globalSearch-instructions-operator-modified'],
|
||||
|
|
|
@ -105,6 +105,14 @@ template(name="boardCardSettingsPopup")
|
|||
span
|
||||
i.fa.fa-users
|
||||
| {{_ 'members'}}
|
||||
|
||||
div.check-div
|
||||
a.flex.js-field-has-creator(class="{{#if allowsCreator}}is-checked{{/if}}")
|
||||
.materialCheckBox(class="{{#if allowsCreator}}is-checked{{/if}}")
|
||||
span
|
||||
i.fa.fa-user
|
||||
| {{_ 'creator'}}
|
||||
|
||||
div.check-div
|
||||
a.flex.js-field-has-assignee(class="{{#if allowsAssignee}}is-checked{{/if}}")
|
||||
.materialCheckBox(class="{{#if allowsAssignee}}is-checked{{/if}}")
|
||||
|
|
|
@ -730,6 +730,14 @@ BlazeComponent.extendComponent({
|
|||
return this.currentBoard.allowsSubtasks;
|
||||
},
|
||||
|
||||
allowsCreator() {
|
||||
return (
|
||||
this.currentBoard.allowsCreator === null ||
|
||||
this.currentBoard.allowsCreator === undefined ||
|
||||
this.currentBoard.allowsCreator
|
||||
);
|
||||
},
|
||||
|
||||
allowsMembers() {
|
||||
return this.currentBoard.allowsMembers;
|
||||
},
|
||||
|
@ -889,6 +897,19 @@ BlazeComponent.extendComponent({
|
|||
this.currentBoard.allowsSubtasks,
|
||||
);
|
||||
},
|
||||
'click .js-field-has-creator'(evt) {
|
||||
evt.preventDefault();
|
||||
this.currentBoard.allowsCreator = !this.currentBoard.allowsCreator;
|
||||
this.currentBoard.setAllowsCreator(this.currentBoard.allowsCreator);
|
||||
$(`.js-field-has-creator ${MCB}`).toggleClass(
|
||||
CKCLS,
|
||||
this.currentBoard.allowsCreator,
|
||||
);
|
||||
$('.js-field-has-creator').toggleClass(
|
||||
CKCLS,
|
||||
this.currentBoard.allowsCreator,
|
||||
);
|
||||
},
|
||||
'click .js-field-has-members'(evt) {
|
||||
evt.preventDefault();
|
||||
this.currentBoard.allowsMembers = !this.currentBoard.allowsMembers;
|
||||
|
|
|
@ -72,9 +72,10 @@ template(name="cardMemberPopup")
|
|||
h3= user.profile.fullname
|
||||
p.quiet @{{ user.username }}
|
||||
ul.pop-over-list
|
||||
if currentUser.isNotCommentOnly
|
||||
if currentUser.isNotWorker
|
||||
li: a.js-remove-member {{_ 'remove-member-from-card'}}
|
||||
unless noRemove
|
||||
if currentUser.isNotCommentOnly
|
||||
if currentUser.isNotWorker
|
||||
li: a.js-remove-member {{_ 'remove-member-from-card'}}
|
||||
|
||||
if $eq currentUser._id user._id
|
||||
with currentUser
|
||||
|
|
|
@ -32,6 +32,7 @@ Template.userAvatar.helpers({
|
|||
|
||||
Template.userAvatar.events({
|
||||
'click .js-change-avatar': Popup.open('changeAvatar'),
|
||||
'click .js-member': Popup.open('cardMember'),
|
||||
});
|
||||
|
||||
Template.userAvatarInitials.helpers({
|
||||
|
|
|
@ -72,7 +72,7 @@ export class CardSearchPagedComponent extends BlazeComponent {
|
|||
if (this.queryErrors.length) {
|
||||
// console.log('queryErrors:', this.queryErrorMessages());
|
||||
this.hasQueryErrors.set(true);
|
||||
return null;
|
||||
// return null;
|
||||
}
|
||||
|
||||
if (cards) {
|
||||
|
|
51
config/const.js
Normal file
51
config/const.js
Normal file
|
@ -0,0 +1,51 @@
|
|||
export const ALLOWED_BOARD_COLORS = [
|
||||
'belize',
|
||||
'nephritis',
|
||||
'pomegranate',
|
||||
'pumpkin',
|
||||
'wisteria',
|
||||
'moderatepink',
|
||||
'strongcyan',
|
||||
'limegreen',
|
||||
'midnight',
|
||||
'dark',
|
||||
'relax',
|
||||
'corteza',
|
||||
'clearblue',
|
||||
'natural',
|
||||
'modern',
|
||||
'moderndark',
|
||||
];
|
||||
export const ALLOWED_COLORS = [
|
||||
'white',
|
||||
'green',
|
||||
'yellow',
|
||||
'orange',
|
||||
'red',
|
||||
'purple',
|
||||
'blue',
|
||||
'sky',
|
||||
'lime',
|
||||
'pink',
|
||||
'black',
|
||||
'silver',
|
||||
'peachpuff',
|
||||
'crimson',
|
||||
'plum',
|
||||
'darkgreen',
|
||||
'slateblue',
|
||||
'magenta',
|
||||
'gold',
|
||||
'navy',
|
||||
'gray',
|
||||
'saddlebrown',
|
||||
'paleturquoise',
|
||||
'mistyrose',
|
||||
'indigo',
|
||||
];
|
||||
export const TYPE_BOARD = 'board';
|
||||
export const TYPE_CARD = 'cardType-card';
|
||||
export const TYPE_LINKED_BOARD = 'cardType-linkedBoard';
|
||||
export const TYPE_LINKED_CARD = 'cardType-linkedCard';
|
||||
export const TYPE_TEMPLATE_BOARD = 'template-board';
|
||||
export const TYPE_TEMPLATE_CONTAINER = 'template-container';
|
|
@ -3,6 +3,7 @@ import {
|
|||
OPERATOR_BOARD,
|
||||
OPERATOR_COMMENT,
|
||||
OPERATOR_CREATED_AT,
|
||||
OPERATOR_CREATOR,
|
||||
OPERATOR_DUE,
|
||||
OPERATOR_HAS,
|
||||
OPERATOR_LABEL,
|
||||
|
@ -107,6 +108,7 @@ export class QueryErrors {
|
|||
[OPERATOR_USER, 'user-username-not-found'],
|
||||
[OPERATOR_ASSIGNEE, 'user-username-not-found'],
|
||||
[OPERATOR_MEMBER, 'user-username-not-found'],
|
||||
[OPERATOR_CREATOR, 'user-username-not-found'],
|
||||
];
|
||||
|
||||
constructor() {
|
||||
|
@ -238,6 +240,7 @@ export class Query {
|
|||
'operator-member': OPERATOR_MEMBER,
|
||||
'operator-member-abbrev': OPERATOR_MEMBER,
|
||||
'operator-assignee': OPERATOR_ASSIGNEE,
|
||||
'operator-creator': OPERATOR_CREATOR,
|
||||
'operator-assignee-abbrev': OPERATOR_ASSIGNEE,
|
||||
'operator-status': OPERATOR_STATUS,
|
||||
'operator-due': OPERATOR_DUE,
|
||||
|
|
|
@ -1,14 +1,15 @@
|
|||
export const DEFAULT_LIMIT = 25;
|
||||
export const OPERATOR_ASSIGNEE = 'assignee';
|
||||
export const OPERATOR_ASSIGNEE = 'assignees';
|
||||
export const OPERATOR_COMMENT = 'comment';
|
||||
export const OPERATOR_CREATED_AT = 'createdAt';
|
||||
export const OPERATOR_CREATOR = 'userId';
|
||||
export const OPERATOR_DUE = 'dueAt';
|
||||
export const OPERATOR_BOARD = 'board';
|
||||
export const OPERATOR_HAS = 'has';
|
||||
export const OPERATOR_LABEL = 'label';
|
||||
export const OPERATOR_LIMIT = 'limit';
|
||||
export const OPERATOR_LIST = 'list';
|
||||
export const OPERATOR_MEMBER = 'member';
|
||||
export const OPERATOR_MEMBER = 'members';
|
||||
export const OPERATOR_MODIFIED_AT = 'modifiedAt';
|
||||
export const OPERATOR_SORT = 'sort';
|
||||
export const OPERATOR_STATUS = 'status';
|
||||
|
|
|
@ -901,6 +901,7 @@
|
|||
"operator-member-abbrev": "m",
|
||||
"operator-assignee": "assignee",
|
||||
"operator-assignee-abbrev": "a",
|
||||
"operator-creator": "creator",
|
||||
"operator-status": "status",
|
||||
"operator-due": "due",
|
||||
"operator-created": "created",
|
||||
|
@ -952,6 +953,7 @@
|
|||
"globalSearch-instructions-operator-at": "`__operator_user_abbrev__username` - shorthand for `user:<username>`",
|
||||
"globalSearch-instructions-operator-member": "`__operator_member__:<username>` - cards where *<username>* is a *member*",
|
||||
"globalSearch-instructions-operator-assignee": "`__operator_assignee__:<username>` - cards where *<username>* is an *assignee*",
|
||||
"globalSearch-instructions-operator-creator": "`__operator_creator__:<username>` - cards where *<username>* is the card's creator",
|
||||
"globalSearch-instructions-operator-due": "`__operator_due__:<n>` - cards which are due up to *<n>* days from now. `__operator_due__:__predicate_overdue__ lists all cards past their due date.",
|
||||
"globalSearch-instructions-operator-created": "`__operator_created__:<n>` - cards which were created *<n>* days ago or less",
|
||||
"globalSearch-instructions-operator-modified": "`__operator_modified__:<n>` - cards which were modified *<n>* days ago or less",
|
||||
|
@ -988,5 +990,6 @@
|
|||
"hide-system-messages-of-all-users": "Hide system messages of all users",
|
||||
"now-system-messages-of-all-users-are-hidden": "Now system messages of all users are hidden",
|
||||
"move-swimlane": "Move Swimlane",
|
||||
"moveSwimlanePopup-title": "Move Swimlane"
|
||||
"moveSwimlanePopup-title": "Move Swimlane",
|
||||
"creator": "Creator"
|
||||
}
|
||||
|
|
|
@ -1,3 +1,11 @@
|
|||
import {
|
||||
ALLOWED_BOARD_COLORS,
|
||||
ALLOWED_COLORS,
|
||||
TYPE_BOARD,
|
||||
TYPE_TEMPLATE_BOARD,
|
||||
TYPE_TEMPLATE_CONTAINER,
|
||||
} from '/config/const';
|
||||
|
||||
const escapeForRegex = require('escape-string-regexp');
|
||||
Boards = new Mongo.Collection('boards');
|
||||
|
||||
|
@ -144,32 +152,7 @@ Boards.attachSchema(
|
|||
* `saddlebrown`, `paleturquoise`, `mistyrose`, `indigo`
|
||||
*/
|
||||
type: String,
|
||||
allowedValues: [
|
||||
'green',
|
||||
'yellow',
|
||||
'orange',
|
||||
'red',
|
||||
'purple',
|
||||
'blue',
|
||||
'sky',
|
||||
'lime',
|
||||
'pink',
|
||||
'black',
|
||||
'silver',
|
||||
'peachpuff',
|
||||
'crimson',
|
||||
'plum',
|
||||
'darkgreen',
|
||||
'slateblue',
|
||||
'magenta',
|
||||
'gold',
|
||||
'navy',
|
||||
'gray',
|
||||
'saddlebrown',
|
||||
'paleturquoise',
|
||||
'mistyrose',
|
||||
'indigo',
|
||||
],
|
||||
allowedValues: ALLOWED_COLORS,
|
||||
},
|
||||
// XXX We might want to maintain more informations under the member sub-
|
||||
// documents like de-normalized meta-data (the date the member joined the
|
||||
|
@ -246,28 +229,11 @@ Boards.attachSchema(
|
|||
* The color of the board.
|
||||
*/
|
||||
type: String,
|
||||
allowedValues: [
|
||||
'belize',
|
||||
'nephritis',
|
||||
'pomegranate',
|
||||
'pumpkin',
|
||||
'wisteria',
|
||||
'moderatepink',
|
||||
'strongcyan',
|
||||
'limegreen',
|
||||
'midnight',
|
||||
'dark',
|
||||
'relax',
|
||||
'corteza',
|
||||
'clearblue',
|
||||
'natural',
|
||||
'modern',
|
||||
'moderndark',
|
||||
],
|
||||
allowedValues: ALLOWED_BOARD_COLORS,
|
||||
// eslint-disable-next-line consistent-return
|
||||
autoValue() {
|
||||
if (this.isInsert && !this.isSet) {
|
||||
return Boards.simpleSchema()._schema.color.allowedValues[0];
|
||||
return ALLOWED_BOARD_COLORS[0];
|
||||
}
|
||||
},
|
||||
},
|
||||
|
@ -372,6 +338,14 @@ Boards.attachSchema(
|
|||
defaultValue: true,
|
||||
},
|
||||
|
||||
allowsCreator: {
|
||||
/**
|
||||
* Does the board allow creator?
|
||||
*/
|
||||
type: Boolean,
|
||||
defaultValue: true,
|
||||
},
|
||||
|
||||
allowsAssignee: {
|
||||
/**
|
||||
* Does the board allows assignee?
|
||||
|
@ -497,9 +471,11 @@ Boards.attachSchema(
|
|||
type: {
|
||||
/**
|
||||
* The type of board
|
||||
* possible values: board, template-board, template-container
|
||||
*/
|
||||
type: String,
|
||||
defaultValue: 'board',
|
||||
defaultValue: TYPE_BOARD,
|
||||
allowedValues: [TYPE_BOARD, TYPE_TEMPLATE_BOARD, TYPE_TEMPLATE_CONTAINER],
|
||||
},
|
||||
sort: {
|
||||
/**
|
||||
|
@ -1187,6 +1163,10 @@ Boards.mutations({
|
|||
return { $set: { allowsSubtasks } };
|
||||
},
|
||||
|
||||
setAllowsCreator(allowsCreator) {
|
||||
return { $set: { allowsCreator } };
|
||||
},
|
||||
|
||||
setAllowsMembers(allowsMembers) {
|
||||
return { $set: { allowsMembers } };
|
||||
},
|
||||
|
@ -1318,8 +1298,11 @@ Boards.userBoards = (userId, archived = false, selector = {}) => {
|
|||
if (typeof archived === 'boolean') {
|
||||
selector.archived = archived;
|
||||
}
|
||||
selector.$or = [{ permission: 'public' }];
|
||||
if (!selector.type) {
|
||||
selector.type = 'board';
|
||||
}
|
||||
|
||||
selector.$or = [{ permission: 'public' }];
|
||||
if (userId) {
|
||||
selector.$or.push({ members: { $elemMatch: { userId, isActive: true } } });
|
||||
}
|
||||
|
@ -1341,7 +1324,7 @@ Boards.colorMap = () => {
|
|||
};
|
||||
|
||||
Boards.labelColors = () => {
|
||||
return _.clone(Boards.simpleSchema()._schema['labels.$.color'].allowedValues);
|
||||
return ALLOWED_COLORS;
|
||||
};
|
||||
|
||||
if (Meteor.isServer) {
|
||||
|
@ -1423,17 +1406,15 @@ if (Meteor.isServer) {
|
|||
},
|
||||
myLabelNames() {
|
||||
let names = [];
|
||||
Boards.userBoards(Meteor.userId(), false, { type: 'board' }).forEach(
|
||||
board => {
|
||||
names = names.concat(
|
||||
board.labels
|
||||
.filter(label => !!label.name)
|
||||
.map(label => {
|
||||
return label.name;
|
||||
}),
|
||||
);
|
||||
},
|
||||
);
|
||||
Boards.userBoards(Meteor.userId()).forEach(board => {
|
||||
names = names.concat(
|
||||
board.labels
|
||||
.filter(label => !!label.name)
|
||||
.map(label => {
|
||||
return label.name;
|
||||
}),
|
||||
);
|
||||
});
|
||||
return _.uniq(names).sort();
|
||||
},
|
||||
myBoardNames() {
|
||||
|
|
|
@ -1,3 +1,10 @@
|
|||
import {
|
||||
ALLOWED_COLORS,
|
||||
TYPE_CARD,
|
||||
TYPE_LINKED_BOARD,
|
||||
TYPE_LINKED_CARD,
|
||||
} from '../config/const';
|
||||
|
||||
Cards = new Mongo.Collection('cards');
|
||||
|
||||
// XXX To improve pub/sub performances a card document should include a
|
||||
|
@ -77,33 +84,7 @@ Cards.attachSchema(
|
|||
color: {
|
||||
type: String,
|
||||
optional: true,
|
||||
allowedValues: [
|
||||
'white',
|
||||
'green',
|
||||
'yellow',
|
||||
'orange',
|
||||
'red',
|
||||
'purple',
|
||||
'blue',
|
||||
'sky',
|
||||
'lime',
|
||||
'pink',
|
||||
'black',
|
||||
'silver',
|
||||
'peachpuff',
|
||||
'crimson',
|
||||
'plum',
|
||||
'darkgreen',
|
||||
'slateblue',
|
||||
'magenta',
|
||||
'gold',
|
||||
'navy',
|
||||
'gray',
|
||||
'saddlebrown',
|
||||
'paleturquoise',
|
||||
'mistyrose',
|
||||
'indigo',
|
||||
],
|
||||
allowedValues: ALLOWED_COLORS,
|
||||
},
|
||||
createdAt: {
|
||||
/**
|
||||
|
@ -301,7 +282,8 @@ Cards.attachSchema(
|
|||
* type of the card
|
||||
*/
|
||||
type: String,
|
||||
defaultValue: 'cardType-card',
|
||||
defaultValue: TYPE_CARD,
|
||||
allowedValues: [TYPE_CARD, TYPE_LINKED_CARD, TYPE_LINKED_BOARD],
|
||||
},
|
||||
linkedId: {
|
||||
/**
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
import { ALLOWED_COLORS } from '/config/const';
|
||||
|
||||
Lists = new Mongo.Collection('lists');
|
||||
|
||||
/**
|
||||
|
@ -144,32 +146,7 @@ Lists.attachSchema(
|
|||
type: String,
|
||||
optional: true,
|
||||
// silver is the default, so it is left out
|
||||
allowedValues: [
|
||||
'white',
|
||||
'green',
|
||||
'yellow',
|
||||
'orange',
|
||||
'red',
|
||||
'purple',
|
||||
'blue',
|
||||
'sky',
|
||||
'lime',
|
||||
'pink',
|
||||
'black',
|
||||
'peachpuff',
|
||||
'crimson',
|
||||
'plum',
|
||||
'darkgreen',
|
||||
'slateblue',
|
||||
'magenta',
|
||||
'gold',
|
||||
'navy',
|
||||
'gray',
|
||||
'saddlebrown',
|
||||
'paleturquoise',
|
||||
'mistyrose',
|
||||
'indigo',
|
||||
],
|
||||
allowedValues: ALLOWED_COLORS,
|
||||
},
|
||||
type: {
|
||||
/**
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
import { ALLOWED_COLORS } from '/config/const';
|
||||
|
||||
Swimlanes = new Mongo.Collection('swimlanes');
|
||||
|
||||
/**
|
||||
|
@ -68,32 +70,7 @@ Swimlanes.attachSchema(
|
|||
type: String,
|
||||
optional: true,
|
||||
// silver is the default, so it is left out
|
||||
allowedValues: [
|
||||
'white',
|
||||
'green',
|
||||
'yellow',
|
||||
'orange',
|
||||
'red',
|
||||
'purple',
|
||||
'blue',
|
||||
'sky',
|
||||
'lime',
|
||||
'pink',
|
||||
'black',
|
||||
'peachpuff',
|
||||
'crimson',
|
||||
'plum',
|
||||
'darkgreen',
|
||||
'slateblue',
|
||||
'magenta',
|
||||
'gold',
|
||||
'navy',
|
||||
'gray',
|
||||
'saddlebrown',
|
||||
'paleturquoise',
|
||||
'mistyrose',
|
||||
'indigo',
|
||||
],
|
||||
allowedValues: ALLOWED_COLORS,
|
||||
},
|
||||
updatedAt: {
|
||||
/**
|
||||
|
|
|
@ -15,12 +15,15 @@ import {
|
|||
OPERATOR_ASSIGNEE,
|
||||
OPERATOR_BOARD,
|
||||
OPERATOR_COMMENT,
|
||||
OPERATOR_CREATED_AT,
|
||||
OPERATOR_CREATOR,
|
||||
OPERATOR_DUE,
|
||||
OPERATOR_HAS,
|
||||
OPERATOR_LABEL,
|
||||
OPERATOR_LIMIT,
|
||||
OPERATOR_LIST,
|
||||
OPERATOR_MEMBER,
|
||||
OPERATOR_MODIFIED_AT,
|
||||
OPERATOR_SORT,
|
||||
OPERATOR_STATUS,
|
||||
OPERATOR_SWIMLANE,
|
||||
|
@ -99,7 +102,7 @@ function buildSelector(queryParams) {
|
|||
let selector = {};
|
||||
|
||||
// eslint-disable-next-line no-console
|
||||
// console.log('queryParams:', queryParams);
|
||||
console.log('queryParams:', queryParams);
|
||||
|
||||
if (queryParams.selector) {
|
||||
selector = queryParams.selector;
|
||||
|
@ -163,7 +166,7 @@ function buildSelector(queryParams) {
|
|||
|
||||
if (queryParams.hasOperator(OPERATOR_BOARD)) {
|
||||
const queryBoards = [];
|
||||
queryParams.hasOperator(OPERATOR_BOARD).forEach(query => {
|
||||
queryParams.getPredicates(OPERATOR_BOARD).forEach(query => {
|
||||
const boards = Boards.userSearch(userId, {
|
||||
title: new RegExp(escapeForRegex(query), 'i'),
|
||||
});
|
||||
|
@ -240,7 +243,7 @@ function buildSelector(queryParams) {
|
|||
}
|
||||
}
|
||||
|
||||
[OPERATOR_DUE, 'createdAt', 'modifiedAt'].forEach(field => {
|
||||
[OPERATOR_DUE, OPERATOR_CREATED_AT, OPERATOR_MODIFIED_AT].forEach(field => {
|
||||
if (queryParams.hasOperator(field)) {
|
||||
selector[field] = {};
|
||||
const predicate = queryParams.getPredicate(field);
|
||||
|
@ -251,57 +254,46 @@ function buildSelector(queryParams) {
|
|||
const queryUsers = {};
|
||||
queryUsers[OPERATOR_ASSIGNEE] = [];
|
||||
queryUsers[OPERATOR_MEMBER] = [];
|
||||
queryUsers[OPERATOR_CREATOR] = [];
|
||||
|
||||
if (queryParams.hasOperator(OPERATOR_USER)) {
|
||||
const users = [];
|
||||
queryParams.getPredicates(OPERATOR_USER).forEach(username => {
|
||||
const user = Users.findOne({ username });
|
||||
if (user) {
|
||||
queryUsers[OPERATOR_MEMBER].push(user._id);
|
||||
queryUsers[OPERATOR_ASSIGNEE].push(user._id);
|
||||
users.push(user._id);
|
||||
} else {
|
||||
errors.addNotFound(OPERATOR_USER, username);
|
||||
}
|
||||
});
|
||||
if (users.length) {
|
||||
selector.$and.push({
|
||||
$or: [{ members: { $in: users } }, { assignees: { $in: users } }],
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
[OPERATOR_MEMBER, OPERATOR_ASSIGNEE].forEach(key => {
|
||||
[OPERATOR_MEMBER, OPERATOR_ASSIGNEE, OPERATOR_CREATOR].forEach(key => {
|
||||
if (queryParams.hasOperator(key)) {
|
||||
queryParams.getPredicates(key).forEach(query => {
|
||||
const users = Users.find({
|
||||
username: query,
|
||||
});
|
||||
if (users.count()) {
|
||||
users.forEach(user => {
|
||||
queryUsers[key].push(user._id);
|
||||
});
|
||||
const users = [];
|
||||
queryParams.getPredicates(key).forEach(username => {
|
||||
const user = Users.findOne({ username });
|
||||
if (user) {
|
||||
users.push(user._id);
|
||||
} else {
|
||||
errors.addNotFound(key, query);
|
||||
errors.addNotFound(key, username);
|
||||
}
|
||||
});
|
||||
if (users.length) {
|
||||
selector[key] = { $in: users };
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if (
|
||||
queryUsers[OPERATOR_MEMBER].length &&
|
||||
queryUsers[OPERATOR_ASSIGNEE].length
|
||||
) {
|
||||
selector.$and.push({
|
||||
$or: [
|
||||
{ members: { $in: queryUsers[OPERATOR_MEMBER] } },
|
||||
{ assignees: { $in: queryUsers[OPERATOR_ASSIGNEE] } },
|
||||
],
|
||||
});
|
||||
} else if (queryUsers[OPERATOR_MEMBER].length) {
|
||||
selector.members = { $in: queryUsers[OPERATOR_MEMBER] };
|
||||
} else if (queryUsers[OPERATOR_ASSIGNEE].length) {
|
||||
selector.assignees = { $in: queryUsers[OPERATOR_ASSIGNEE] };
|
||||
}
|
||||
|
||||
if (queryParams.hasOperator(OPERATOR_LABEL)) {
|
||||
const queryLabels = [];
|
||||
queryParams.getPredicates(OPERATOR_LABEL).forEach(label => {
|
||||
const queryLabels = [];
|
||||
|
||||
let boards = Boards.userSearch(userId, {
|
||||
let boards = Boards.userBoards(userId, null, {
|
||||
labels: { $elemMatch: { color: label.toLowerCase() } },
|
||||
});
|
||||
|
||||
|
@ -325,7 +317,7 @@ function buildSelector(queryParams) {
|
|||
const reLabel = new RegExp(escapeForRegex(label), 'i');
|
||||
// eslint-disable-next-line no-console
|
||||
// console.log('reLabel:', reLabel);
|
||||
boards = Boards.userSearch(userId, {
|
||||
boards = Boards.userBoards(userId, null, {
|
||||
labels: { $elemMatch: { name: reLabel } },
|
||||
});
|
||||
|
||||
|
@ -346,9 +338,12 @@ function buildSelector(queryParams) {
|
|||
errors.addNotFound(OPERATOR_LABEL, label);
|
||||
}
|
||||
}
|
||||
|
||||
selector.labelIds = { $in: _.uniq(queryLabels) };
|
||||
});
|
||||
if (queryLabels.length) {
|
||||
// eslint-disable-next-line no-console
|
||||
// console.log('queryLabels:', queryLabels);
|
||||
selector.labelIds = { $in: _.uniq(queryLabels) };
|
||||
}
|
||||
}
|
||||
|
||||
if (queryParams.hasOperator(OPERATOR_HAS)) {
|
||||
|
@ -443,9 +438,9 @@ function buildSelector(queryParams) {
|
|||
}
|
||||
|
||||
// eslint-disable-next-line no-console
|
||||
// console.log('selector:', selector);
|
||||
console.log('selector:', selector);
|
||||
// eslint-disable-next-line no-console
|
||||
// console.log('selector.$and:', selector.$and);
|
||||
console.log('selector.$and:', selector.$and);
|
||||
|
||||
const query = new Query();
|
||||
query.selector = selector;
|
||||
|
@ -488,6 +483,7 @@ function buildProjection(query) {
|
|||
modifiedAt: 1,
|
||||
labelIds: 1,
|
||||
customFields: 1,
|
||||
userId: 1,
|
||||
},
|
||||
sort: {
|
||||
boardId: 1,
|
||||
|
@ -603,9 +599,9 @@ function findCards(sessionId, query) {
|
|||
// eslint-disable-next-line no-console
|
||||
// console.log('projection:', projection);
|
||||
let cards;
|
||||
if (!query.hasErrors()) {
|
||||
cards = Cards.find(query.selector, query.projection);
|
||||
}
|
||||
// if (!query.hasErrors()) {
|
||||
cards = Cards.find(query.selector, query.projection);
|
||||
// }
|
||||
// eslint-disable-next-line no-console
|
||||
// console.log('count:', cards.count());
|
||||
|
||||
|
@ -658,6 +654,9 @@ function findCards(sessionId, query) {
|
|||
if (card.boardId) boards.push(card.boardId);
|
||||
if (card.swimlaneId) swimlanes.push(card.swimlaneId);
|
||||
if (card.listId) lists.push(card.listId);
|
||||
if (card.userId) {
|
||||
users.push(card.userId);
|
||||
}
|
||||
if (card.members) {
|
||||
card.members.forEach(userId => {
|
||||
users.push(userId);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue