wekan/client/lib/filter.js
Maxime Quandalle 2dbea30842 Renaissance
_,,ad8888888888bba,_
                  ,ad88888I888888888888888ba,
                ,88888888I88888888888888888888a,
              ,d888888888I8888888888888888888888b,
             d88888PP"""" ""YY88888888888888888888b,
           ,d88"'__,,--------,,,,.;ZZZY8888888888888,
          ,8IIl'"                ;;l"ZZZIII8888888888,
         ,I88l;'                  ;lZZZZZ888III8888888,
       ,II88Zl;.                  ;llZZZZZ888888I888888,
      ,II888Zl;.                .;;;;;lllZZZ888888I8888b
     ,II8888Z;;                 `;;;;;''llZZ8888888I8888,
     II88888Z;'                        .;lZZZ8888888I888b
     II88888Z; _,aaa,      .,aaaaa,__.l;llZZZ88888888I888
     II88888IZZZZZZZZZ,  .ZZZZZZZZZZZZZZ;llZZ88888888I888,
     II88888IZZ<'(@@>Z|  |ZZZ<'(@@>ZZZZ;;llZZ888888888I88I
    ,II88888;   `""" ;|  |ZZ; `"""     ;;llZ8888888888I888
    II888888l            `;;          .;llZZ8888888888I888,
   ,II888888Z;           ;;;        .;;llZZZ8888888888I888I
   III888888Zl;    ..,   `;;       ,;;lllZZZ88888888888I888
   II88888888Z;;...;(_    _)      ,;;;llZZZZ88888888888I888,
   II88888888Zl;;;;;' `--'Z;.   .,;;;;llZZZZ88888888888I888b
   ]I888888888Z;;;;'   ";llllll;..;;;lllZZZZ88888888888I8888,
   II888888888Zl.;;"Y88bd888P";;,..;lllZZZZZ88888888888I8888I
   II8888888888Zl;.; `"PPP";;;,..;lllZZZZZZZ88888888888I88888
   II888888888888Zl;;. `;;;l;;;;lllZZZZZZZZW88888888888I88888
   `II8888888888888Zl;.    ,;;lllZZZZZZZZWMZ88888888888I88888
    II8888888888888888ZbaalllZZZZZZZZZWWMZZZ8888888888I888888,
    `II88888888888888888b"WWZZZZZWWWMMZZZZZZI888888888I888888b
     `II88888888888888888;ZZMMMMMMZZZZZZZZllI888888888I8888888
      `II8888888888888888 `;lZZZZZZZZZZZlllll888888888I8888888,
       II8888888888888888, `;lllZZZZllllll;;.Y88888888I8888888b,
      ,II8888888888888888b   .;;lllllll;;;.;..88888888I88888888b,
      II888888888888888PZI;.  .`;;;.;;;..; ...88888888I8888888888,
      II888888888888PZ;;';;.   ;. .;.  .;. .. Y8888888I88888888888b,
     ,II888888888PZ;;'                        `8888888I8888888888888b,
     II888888888'                              888888I8888888888888888
    ,II888888888                              ,888888I8888888888888888
   ,d88888888888                              d888888I8888888888ZZZZZZ
,ad888888888888I                              8888888I8888ZZZZZZZZZZZZ
888888888888888'                              888888IZZZZZZZZZZZZZZZZZ
8888888888P'8P'                               Y888ZZZZZZZZZZZZZZZZZZZZ
888888888,  "                                 ,ZZZZZZZZZZZZZZZZZZZZZZZ
8888888888,                                ,ZZZZZZZZZZZZZZZZZZZZZZZZZZ
888888888888a,      _                    ,ZZZZZZZZZZZZZZZZZZZZ88888888
888888888888888ba,_d'                  ,ZZZZZZZZZZZZZZZZZ8888888888888
8888888888888888888888bbbaaa,,,______,ZZZZZZZZZZZZZZZ88888888888888888
88888888888888888888888888888888888ZZZZZZZZZZZZZZZ88888888888888888888
8888888888888888888888888888888888ZZZZZZZZZZZZZZ8888888888888888888888
888888888888888888888888888888888ZZZZZZZZZZZZZZ88888888888888888888888
8888888888888888888888888888888ZZZZZZZZZZZZZZ8888888888888888888888888
88888888888888888888888888888ZZZZZZZZZZZZZZ888888888888888888888888888
8888888888888888888888888888ZZZZZZZZZZZZZZ88888888888888888 Normand  8
88888888888888888888888888ZZZZZZZZZZZZZZ8888888888888888888 Veilleux 8
8888888888888888888888888ZZZZZZZZZZZZZZ8888888888888888888888888888888
2015-05-12 19:33:50 +02:00

133 lines
3.5 KiB
JavaScript

// Filtered view manager
// We define local filter objects for each different type of field (SetFilter,
// RangeFilter, dateFilter, etc.). We then define a global `Filter` object whose
// goal is to filter complete documents by using the local filters for each
// fields.
// Use a "set" filter for a field that is a set of documents uniquely
// identified. For instance `{ labels: ['labelA', 'labelC', 'labelD'] }`.
var SetFilter = function() {
this._dep = new Tracker.Dependency();
this._selectedElements = [];
};
_.extend(SetFilter.prototype, {
isSelected: function(val) {
this._dep.depend();
return this._selectedElements.indexOf(val) > -1;
},
add: function(val) {
if (this.indexOfVal(val) === -1) {
this._selectedElements.push(val);
this._dep.changed();
}
},
remove: function(val) {
var indexOfVal = this._indexOfVal(val);
if (this.indexOfVal(val) !== -1) {
this._selectedElements.splice(indexOfVal, 1);
this._dep.changed();
}
},
toogle: function(val) {
var indexOfVal = this._indexOfVal(val);
if (indexOfVal === -1) {
this._selectedElements.push(val);
} else {
this._selectedElements.splice(indexOfVal, 1);
}
this._dep.changed();
},
reset: function() {
this._selectedElements = [];
this._dep.changed();
},
_indexOfVal: function(val) {
return this._selectedElements.indexOf(val);
},
_isActive: function() {
this._dep.depend();
return this._selectedElements.length !== 0;
},
_getMongoSelector: function() {
this._dep.depend();
return { $in: this._selectedElements };
}
});
// 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
// object prototype.
Filter = {
// XXX I would like to rename this field into `labels` to be consistent with
// the rest of the schema, but we need to set some migrations architecture
// before changing the schema.
labelIds: new SetFilter(),
members: new SetFilter(),
_fields: ['labelIds', 'members'],
// We don't filter cards that have been added after the last filter change. To
// implement this we keep the id of these cards in this `_exceptions` fields
// and use a `$or` condition in the mongo selector we return.
_exceptions: [],
_exceptionsDep: new Tracker.Dependency(),
isActive: function() {
var self = this;
return _.any(self._fields, function(fieldName) {
return self[fieldName]._isActive();
});
},
getMongoSelector: function() {
var self = this;
if (! self.isActive())
return {};
var filterSelector = {};
_.forEach(self._fields, function(fieldName) {
var filter = self[fieldName];
if (filter._isActive())
filterSelector[fieldName] = filter._getMongoSelector();
});
var exceptionsSelector = {_id: {$in: this._exceptions}};
this._exceptionsDep.depend();
return {$or: [filterSelector, exceptionsSelector]};
},
reset: function() {
var self = this;
_.forEach(self._fields, function(fieldName) {
var filter = self[fieldName];
filter.reset();
});
self.resetExceptions();
},
addException: function(_id) {
if (this.isActive()) {
this._exceptions.push(_id);
this._exceptionsDep.changed();
}
},
resetExceptions: function() {
this._exceptions = [];
this._exceptionsDep.changed();
}
};
Blaze.registerHelper('Filter', Filter);