Skip to content

Commit

Permalink
Add filter exceptions to DataSource
Browse files Browse the repository at this point in the history
Summary: Filter exceptions allow us to add singular items to table views. Extremely useful for Bloks Debugger where we have to jump between multiple types of rows that could be filtered out

Reviewed By: LukeDefeo

Differential Revision: D47472006

fbshipit-source-id: 74d21a65d364ec5ab88652effc06aade20ad80b2
  • Loading branch information
aigoncharov authored and facebook-github-bot committed Jul 18, 2023
1 parent cba5af6 commit 8397b2b
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 2 deletions.
29 changes: 29 additions & 0 deletions desktop/flipper-plugin-core/src/data-source/DataSource.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -664,6 +664,7 @@ export class DataSourceView<T, KeyType> {
private sortBy: undefined | ((a: T) => Primitive) = undefined;
private reverse: boolean = false;
private filter?: (value: T) => boolean = undefined;
private filterExceptions?: Set<KeyType> = undefined;

/**
* @readonly
Expand Down Expand Up @@ -760,10 +761,22 @@ export class DataSourceView<T, KeyType> {
public setFilter(filter: undefined | ((value: T) => boolean)) {
if (this.filter !== filter) {
this.filter = filter;
// Filter exceptions are relevant for one filter only
this.filterExceptions = undefined;
this.rebuild();
}
}

/**
* Granular control over filters to add one-off exceptions to them.
* They allow us to add singular items to table views.
* Extremely useful for Bloks Debugger where we have to jump between multiple types of rows that could be filtered out
*/
public setFilterExpections(ids: KeyType[]) {
this.filterExceptions = new Set(ids);
this.rebuild();
}

public toggleReversed() {
this.setReversed(!this.reverse);
}
Expand All @@ -782,6 +795,7 @@ export class DataSourceView<T, KeyType> {
this.sortBy = undefined;
this.reverse = false;
this.filter = undefined;
this.filterExceptions = undefined;
this.windowStart = 0;
this.windowEnd = 0;
this.rebuild();
Expand Down Expand Up @@ -891,6 +905,7 @@ export class DataSourceView<T, KeyType> {
case 'append': {
const {entry} = event;
entry.visible[this.viewId] = filter ? filter(entry.value) : true;
this.applyFilterExceptions(entry);
if (!entry.visible[this.viewId]) {
// not in filter? skip this entry
return;
Expand All @@ -908,6 +923,7 @@ export class DataSourceView<T, KeyType> {
case 'update': {
const {entry} = event;
entry.visible[this.viewId] = filter ? filter(entry.value) : true;
this.applyFilterExceptions(entry);
// short circuit; no view active so update straight away
if (!filter && !sortBy) {
output[event.index].approxIndex[this.viewId] = event.index;
Expand Down Expand Up @@ -1015,6 +1031,7 @@ export class DataSourceView<T, KeyType> {
let output = filter
? records.filter((entry) => {
entry.visible[this.viewId] = filter(entry.value);
this.applyFilterExceptions(entry);
return entry.visible[this.viewId];
})
: records.slice();
Expand Down Expand Up @@ -1082,4 +1099,16 @@ export class DataSourceView<T, KeyType> {
this._output.splice(insertionIndex, 0, entry);
this.notifyItemShift(insertionIndex, 1);
}

private applyFilterExceptions(entry: Entry<T>) {
if (
this.datasource.keyAttribute &&
this.filter &&
this.filterExceptions &&
!entry.visible[this.viewId]
) {
const keyValue = entry.value[this.datasource.keyAttribute] as KeyType;
entry.visible[this.viewId] = this.filterExceptions.has(keyValue);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -356,6 +356,21 @@ test('filter', () => {
expect(rawOutput(ds)).toEqual([newCookie, newCoffee, submitBug, a, b]);
});

test('filter + filterExceptions', () => {
const ds = createDataSource<Todo, 'id'>([eatCookie, drinkCoffee, submitBug], {
key: 'id',
});

ds.view.setFilter((t) => t.title.indexOf('c') === -1);

expect(rawOutput(ds)).toEqual([submitBug]);

// add exception
ds.view.setFilterExpections([drinkCoffee.id]);

expect(rawOutput(ds)).toEqual([drinkCoffee, submitBug]);
});

test('reverse without sorting', () => {
const ds = createDataSource<Todo>([eatCookie, drinkCoffee]);
ds.view.setWindow(0, 100);
Expand Down Expand Up @@ -452,8 +467,12 @@ test('reset', () => {
key: 'id',
});
ds.view.setSortBy('title');
ds.view.setFilter((v) => v.id !== 'cookie');
expect(rawOutput(ds)).toEqual([drinkCoffee, submitBug]);
ds.view.setFilter((v) => v.id === 'cookie');
expect(rawOutput(ds)).toEqual([eatCookie]);
expect([...ds.keys()]).toEqual(['bug', 'coffee', 'cookie']);

ds.view.setFilterExpections([drinkCoffee.id]);
expect(rawOutput(ds)).toEqual([drinkCoffee, eatCookie]);
expect([...ds.keys()]).toEqual(['bug', 'coffee', 'cookie']);

ds.view.reset();
Expand Down

0 comments on commit 8397b2b

Please sign in to comment.