summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--client/components/sidebar/sidebarFilters.jade2
-rw-r--r--client/components/sidebar/sidebarFilters.js5
-rw-r--r--client/lib/filter.js113
3 files changed, 118 insertions, 2 deletions
diff --git a/client/components/sidebar/sidebarFilters.jade b/client/components/sidebar/sidebarFilters.jade
index 5f9fcf72..00d8c87b 100644
--- a/client/components/sidebar/sidebarFilters.jade
+++ b/client/components/sidebar/sidebarFilters.jade
@@ -55,6 +55,8 @@ template(name="filterSidebar")
{{ name }}
if Filter.customFields.isSelected _id
i.fa.fa-check
+ hr
+ input.js-field-advanced-filter(type="text")
if Filter.isActive
hr
a.sidebar-btn.js-clear-all
diff --git a/client/components/sidebar/sidebarFilters.js b/client/components/sidebar/sidebarFilters.js
index ba2633de..6fb3f500 100644
--- a/client/components/sidebar/sidebarFilters.js
+++ b/client/components/sidebar/sidebarFilters.js
@@ -16,6 +16,11 @@ BlazeComponent.extendComponent({
Filter.customFields.toggle(this.currentData()._id);
Filter.resetExceptions();
},
+ 'input .js-field-advanced-filter'(evt) {
+ evt.preventDefault();
+ Filter.advanced.set(this.find('.js-field-advanced-filter').value.trim());
+ Filter.resetExceptions();
+ },
'click .js-clear-all'(evt) {
evt.preventDefault();
Filter.reset();
diff --git a/client/lib/filter.js b/client/lib/filter.js
index f68c9711..8b7f7574 100644
--- a/client/lib/filter.js
+++ b/client/lib/filter.js
@@ -79,6 +79,110 @@ class SetFilter {
}
}
+
+// Advanced filter forms a MongoSelector from a users String.
+// Build by: Ignatz 19.05.2018 (github feuerball11)
+class AdvancedFilter {
+ constructor() {
+ this._dep = new Tracker.Dependency();
+ this._filter = '';
+ }
+
+ set(str)
+ {
+ this._filter = str;
+ this._dep.changed();
+ }
+
+ reset() {
+ this._filter = '';
+ this._dep.changed();
+ }
+
+ _isActive() {
+ this._dep.depend();
+ return this._filter !== '';
+ }
+
+ _filterToCommands(){
+ const commands = [];
+ let current = '';
+ let string = false;
+ let ignore = false;
+ for (let i = 0; i < this._filter.length; i++)
+ {
+ const char = this._filter.charAt(i);
+ if (ignore)
+ {
+ ignore = false;
+ continue;
+ }
+ if (char === '\'')
+ {
+ string = true;
+ continue;
+ }
+ if (char === '\\')
+ {
+ ignore = true;
+ continue;
+ }
+ if (char === ' ' && !string)
+ {
+ commands.push({'cmd':current, string});
+ string = false;
+ current = '';
+ continue;
+ }
+ current.push(char);
+ }
+ if (current !== '')
+ {
+ commands.push(current);
+ }
+ return commands;
+ }
+
+ _arrayToSelector(commands)
+ {
+ try {
+ //let changed = false;
+ for (let i = 0; i < commands.length; i++)
+ {
+ if (!commands[i].string && commands[i].cmd)
+ {
+ switch (commands[i].cmd)
+ {
+ case '=':
+ case '==':
+ case '===':
+ {
+ const field = commands[i-1];
+ const str = commands[i+1];
+ commands[i] = {}[field]=str;
+ commands.splice(i-1, 1);
+ commands.splice(i, 1);
+ //changed = true;
+ i--;
+ break;
+ }
+
+ }
+ }
+ }
+ }
+ catch (e){return { $in: [] };}
+ return commands;
+ }
+
+ _getMongoSelector() {
+ this._dep.depend();
+ const commands = this._filterToCommands();
+ return this._arrayToSelector(commands);
+ }
+
+}
+
// The global Filter object.
// XXX It would be possible to re-write this object more elegantly, and removing
// the need to provide a list of `_fields`. We also should move methods into the
@@ -90,6 +194,7 @@ Filter = {
labelIds: new SetFilter(),
members: new SetFilter(),
customFields: new SetFilter('_id'),
+ advanced: new AdvancedFilter(),
_fields: ['labelIds', 'members', 'customFields'],
@@ -134,9 +239,13 @@ Filter = {
this._exceptionsDep.depend();
if (includeEmptySelectors)
- return {$or: [filterSelector, exceptionsSelector, emptySelector]};
+ return {
+ $or: [filterSelector, exceptionsSelector, this.advanced._getMongoSelector(), emptySelector],
+ };
else
- return {$or: [filterSelector, exceptionsSelector]};
+ return {
+ $or: [filterSelector, exceptionsSelector, this.advanced._getMongoSelector()],
+ };
},
mongoSelector(additionalSelector) {