diff options
Diffstat (limited to 'client')
-rw-r--r-- | client/components/sidebar/sidebarFilters.jade | 2 | ||||
-rw-r--r-- | client/components/sidebar/sidebarFilters.js | 5 | ||||
-rw-r--r-- | client/lib/filter.js | 113 |
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) { |