mirror of
https://github.com/wekan/wekan.git
synced 2026-03-04 21:00:16 +01:00
Add new has operator for searching
This commit is contained in:
parent
c02b71e0e1
commit
726be664c8
4 changed files with 43 additions and 2 deletions
|
|
@ -222,6 +222,7 @@ BlazeComponent.extendComponent({
|
||||||
'operator-created': 'createdAt',
|
'operator-created': 'createdAt',
|
||||||
'operator-modified': 'modifiedAt',
|
'operator-modified': 'modifiedAt',
|
||||||
'operator-comment': 'comments',
|
'operator-comment': 'comments',
|
||||||
|
'operator-has': 'has',
|
||||||
};
|
};
|
||||||
|
|
||||||
const predicates = {
|
const predicates = {
|
||||||
|
|
@ -244,6 +245,11 @@ BlazeComponent.extendComponent({
|
||||||
'predicate-created': 'createdAt',
|
'predicate-created': 'createdAt',
|
||||||
'predicate-modified': 'modifiedAt',
|
'predicate-modified': 'modifiedAt',
|
||||||
},
|
},
|
||||||
|
has: {
|
||||||
|
'predicate-description': 'description',
|
||||||
|
'predicate-checklist': 'checklist',
|
||||||
|
'predicate-attachment': 'attachment',
|
||||||
|
},
|
||||||
};
|
};
|
||||||
const predicateTranslations = {};
|
const predicateTranslations = {};
|
||||||
Object.entries(predicates).forEach(([category, catPreds]) => {
|
Object.entries(predicates).forEach(([category, catPreds]) => {
|
||||||
|
|
@ -276,6 +282,7 @@ BlazeComponent.extendComponent({
|
||||||
createdAt: null,
|
createdAt: null,
|
||||||
modifiedAt: null,
|
modifiedAt: null,
|
||||||
comments: [],
|
comments: [],
|
||||||
|
has: [],
|
||||||
};
|
};
|
||||||
|
|
||||||
let text = '';
|
let text = '';
|
||||||
|
|
@ -296,6 +303,7 @@ BlazeComponent.extendComponent({
|
||||||
} else {
|
} else {
|
||||||
op = m.groups.abbrev.toLowerCase();
|
op = m.groups.abbrev.toLowerCase();
|
||||||
}
|
}
|
||||||
|
// eslint-disable-next-line no-prototype-builtins
|
||||||
if (operatorMap.hasOwnProperty(op)) {
|
if (operatorMap.hasOwnProperty(op)) {
|
||||||
let value = m.groups.value;
|
let value = m.groups.value;
|
||||||
if (operatorMap[op] === 'labels') {
|
if (operatorMap[op] === 'labels') {
|
||||||
|
|
@ -353,6 +361,15 @@ BlazeComponent.extendComponent({
|
||||||
} else {
|
} else {
|
||||||
value = predicateTranslations.status[value];
|
value = predicateTranslations.status[value];
|
||||||
}
|
}
|
||||||
|
} else if (operatorMap[op] === 'has') {
|
||||||
|
if (!predicateTranslations.has[value]) {
|
||||||
|
this.parsingErrors.push({
|
||||||
|
tag: 'operator-has-invalid',
|
||||||
|
value,
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
value = predicateTranslations.has[value];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (Array.isArray(params[operatorMap[op]])) {
|
if (Array.isArray(params[operatorMap[op]])) {
|
||||||
params[operatorMap[op]].push(value);
|
params[operatorMap[op]].push(value);
|
||||||
|
|
|
||||||
|
|
@ -906,6 +906,7 @@
|
||||||
"operator-modified": "modified",
|
"operator-modified": "modified",
|
||||||
"operator-sort": "sort",
|
"operator-sort": "sort",
|
||||||
"operator-comment": "comment",
|
"operator-comment": "comment",
|
||||||
|
"operator-has": "has",
|
||||||
"predicate-archived": "archived",
|
"predicate-archived": "archived",
|
||||||
"predicate-ended": "ended",
|
"predicate-ended": "ended",
|
||||||
"predicate-all": "all",
|
"predicate-all": "all",
|
||||||
|
|
@ -917,10 +918,14 @@
|
||||||
"predicate-due": "due",
|
"predicate-due": "due",
|
||||||
"predicate-modified": "modified",
|
"predicate-modified": "modified",
|
||||||
"predicate-created": "created",
|
"predicate-created": "created",
|
||||||
|
"predicate-attachment": "attachment",
|
||||||
|
"predicate-description": "description",
|
||||||
|
"predicate-checklist": "checklist",
|
||||||
"operator-unknown-error": "%s is not an operator",
|
"operator-unknown-error": "%s is not an operator",
|
||||||
"operator-number-expected": "operator __operator__ expected a number, got '__value__'",
|
"operator-number-expected": "operator __operator__ expected a number, got '__value__'",
|
||||||
"operator-sort-invalid": "sort of '%s' is invalid",
|
"operator-sort-invalid": "sort of '%s' is invalid",
|
||||||
"operator-status-invalid": "'%s' is not a valid status",
|
"operator-status-invalid": "'%s' is not a valid status",
|
||||||
|
"operator-has-invalid": "%s is not a valid existence check",
|
||||||
"next-page": "Next Page",
|
"next-page": "Next Page",
|
||||||
"previous-page": "Previous Page",
|
"previous-page": "Previous Page",
|
||||||
"heading-notes": "Notes",
|
"heading-notes": "Notes",
|
||||||
|
|
|
||||||
|
|
@ -134,7 +134,10 @@ SessionData.helpers({
|
||||||
|
|
||||||
SessionData.unpickle = pickle => {
|
SessionData.unpickle = pickle => {
|
||||||
return JSON.parse(pickle, (key, value) => {
|
return JSON.parse(pickle, (key, value) => {
|
||||||
if (typeof value === 'object') {
|
if (value === null) {
|
||||||
|
return null;
|
||||||
|
} else if (typeof value === 'object') {
|
||||||
|
// eslint-disable-next-line no-prototype-builtins
|
||||||
if (value.hasOwnProperty('$$class')) {
|
if (value.hasOwnProperty('$$class')) {
|
||||||
if (value.$$class === 'RegExp') {
|
if (value.$$class === 'RegExp') {
|
||||||
return new RegExp(value.source, value.flags);
|
return new RegExp(value.source, value.flags);
|
||||||
|
|
@ -147,7 +150,9 @@ SessionData.unpickle = pickle => {
|
||||||
|
|
||||||
SessionData.pickle = value => {
|
SessionData.pickle = value => {
|
||||||
return JSON.stringify(value, (key, value) => {
|
return JSON.stringify(value, (key, value) => {
|
||||||
if (typeof value === 'object') {
|
if (value === null) {
|
||||||
|
return null;
|
||||||
|
} else if (typeof value === 'object') {
|
||||||
if (value.constructor.name === 'RegExp') {
|
if (value.constructor.name === 'RegExp') {
|
||||||
return {
|
return {
|
||||||
$$class: 'RegExp',
|
$$class: 'RegExp',
|
||||||
|
|
|
||||||
|
|
@ -507,6 +507,20 @@ Meteor.publish('globalSearch', function(sessionId, queryParams) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (queryParams.has.length) {
|
||||||
|
queryParams.has.forEach(has => {
|
||||||
|
if (has === 'description') {
|
||||||
|
selector.description = { $exists: true, $nin: [null, ''] };
|
||||||
|
} else if (has === 'attachment') {
|
||||||
|
const attachments = Attachments.find({}, { fields: { cardId: 1 } });
|
||||||
|
selector.$and.push({ _id: { $in: attachments.map(a => a.cardId) } });
|
||||||
|
} else if (has === 'checklist') {
|
||||||
|
const checklists = Checklists.find({}, { fields: { cardId: 1 } });
|
||||||
|
selector.$and.push({ _id: { $in: checklists.map(a => a.cardId) } });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
if (queryParams.text) {
|
if (queryParams.text) {
|
||||||
const regex = new RegExp(escapeForRegex(queryParams.text), 'i');
|
const regex = new RegExp(escapeForRegex(queryParams.text), 'i');
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue