Skip to content

Commit 0ad2738

Browse files
author
Sergei Aksiutin
committed
[NEP-12629] Initial URL filters
1 parent d629f0f commit 0ad2738

18 files changed

+523
-411
lines changed

dist/react-filterbar.js

Lines changed: 158 additions & 138 deletions
Large diffs are not rendered by default.

dist/react-filterbar.min.js

Lines changed: 15 additions & 15 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

example/public/js/react-filterbar.js

Lines changed: 159 additions & 140 deletions
Large diffs are not rendered by default.

example/saved_search.yml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
---
2+
TEST: "[]"
3+
Book 1: "[]"
4+
Book 10: '[[{"field":"title","type":"text","label":"Title","filterUid":"title","uid":"title","value":"Book
5+
10"}]]'
6+
Title wit OR: '[[{"field":"author","type":"select","label":"Author","url":"/authors","default":"Author
7+
31","filterUid":"author","uid":"author","value":"Author 31"}],[{"field":"title","type":"text","label":"Title","filterUid":"title","uid":"title","value":"Book
8+
10"}]]'

example/server.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ def loop_over_queries(queries, haystack)
8282

8383
def search(needle, haystack)
8484
field, type, value = needle.first.values_at(*%w(field type value))
85+
value ||= ""
8586
case type.to_sym
8687
when :date
8788
haystack.select do |hay|

src/actors/FilterBarActor.js

Lines changed: 10 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,8 @@ export class FilterBarActor {
3737
this.filterBarStore.updateFilter(groupKey, inputKey, value);
3838
}
3939

40-
disableFilter(groupKey, inputKey) {
41-
this.filterBarStore.disableFilter(groupKey, inputKey)
40+
clearActiveFilter(groupKey, inputKey) {
41+
this.filterBarStore.clearActiveFilter(groupKey, inputKey)
4242
}
4343

4444
applyFilters() {
@@ -59,14 +59,17 @@ export class FilterBarActor {
5959
}
6060

6161
applyQuickFilter(filterName, value, quickFilterName, blockName) {
62-
let filter = this.filterBarStore.getFilter(filterName)
62+
var filter = this.filterBarStore.getFilter(filterName)
63+
6364
if (filter.type === 'multi_select') {
6465
value = value.split(",").map(function (string) {
6566
return string.trim();
6667
});
6768
}
69+
6870
this.filterBarStore.enableQuickFilter(quickFilterName, blockName);
69-
this.enableFilter(filterName, value);
71+
this.filterBarStore.setActiveFilters([]);
72+
this.filterBarStore.addGroupFilter(filterName, undefined, value);
7073
this.applyFilters();
7174
}
7275

@@ -107,17 +110,9 @@ export class FilterBarActor {
107110
var filters = JSON.parse(savedSearch.configuration);
108111

109112
if (this.verifySavedFilters(filters)) {
110-
if (filters instanceof Array) {
111-
filters.forEach((filter) =>
112-
this.enableFilter(filter.uid, filter.value)
113-
);
114-
} else {
115-
for (var filter in filters) {
116-
this.enableFilter(filter, filters[filter]);
117-
}
118-
}
119-
113+
this.filterBarStore.setActiveFilters(filters);
120114
this.applyFilters();
115+
this.filterBarStore.emitChange();
121116
} else {
122117
this.deleteSavedSearch(searchId, 'One of the filters in this saved search cannot be applied anymore. Remove saved search?');
123118
}
@@ -139,15 +134,7 @@ export class FilterBarActor {
139134
}
140135

141136
saveFilters(name) {
142-
var filters = [];
143-
for (var [filterUid, filter] of this.filterBarStore.enabledFilters()) {
144-
filters.push({
145-
uid: filterUid,
146-
type: filter.type,
147-
field: filter.field,
148-
value: filter.value,
149-
});
150-
}
137+
const filters = this.filterBarStore.getActiveFilters();
151138

152139
var savedSearchPacket = {
153140
saved_search: {

src/app.js

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -48,17 +48,25 @@ function setupConfiguration(configuration) {
4848
configuration.tableConfiguration.page = Number(url.query(true).page);
4949

5050
if (url.query(true).q !== "") {
51-
for (var filter of JSON.parse(url.query(true).q)) {
52-
var configFilter = configuration.filterBarConfiguration.filters[filter.uid];
53-
54-
if (configFilter) {
55-
configFilter.enabled = true;
56-
configFilter.value = filter.value;
57-
58-
if (filter.operator) {
59-
configFilter.operator = filter.operator;
51+
const activeFilters = JSON.parse(url.query(true).q);
52+
configuration.filterBarConfiguration.activeFilters = [];
53+
for (var groupFilters of activeFilters) {
54+
const _groupFilters = []
55+
groupFilters.map(function(filter) {
56+
var configFilter = configuration.filterBarConfiguration.filters[filter.uid];
57+
58+
if (configFilter) {
59+
configFilter.filterUid = filter.uid;
60+
configFilter.uid = filter.uid;
61+
configFilter.value = filter.value;
62+
63+
if (filter.operator) {
64+
configFilter.operator = filter.operator;
65+
}
6066
}
61-
}
67+
_groupFilters.push(configFilter);
68+
});
69+
configuration.filterBarConfiguration.activeFilters.push(_groupFilters);
6270
}
6371
}
6472

src/components/FilterBar/FilterBar.react.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ export class FilterBar extends React.Component {
5353
<FilterDisplay
5454
filterBarActor={this.context.filterBarActor}
5555
filterBarStore={this.context.filterBarStore}
56+
filters={ this.context.filterBarStore.getActiveFilters() }
5657
/>
5758
</div>
5859
</div>

src/components/FilterBar/FilterDisplay/FilterButton.react.js

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -53,11 +53,13 @@ export class FilterButton extends React.Component {
5353
}
5454
}
5555

56+
FilterButton.propTypes = {
57+
filters: React.PropTypes.object.isRequired,
58+
onClick: React.PropTypes.func.isRequired,
59+
title: React.PropTypes.string.isRequired
60+
};
61+
5662
FilterButton.contextTypes = {
5763
filterBarActor: React.PropTypes.object,
5864
filterBarStore: React.PropTypes.object
5965
};
60-
61-
FilterButton.propTypes = {
62-
disabledFilters: React.PropTypes.object.isRequired
63-
};

src/components/FilterBar/FilterDisplay/FilterDisplay.react.js

Lines changed: 42 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -6,39 +6,31 @@ export class FilterDisplay extends React.Component {
66
constructor(props) {
77
super(props);
88

9-
this.state = { filters: props.enabledFilters };
9+
this.state = { filters: props.filters };
1010
}
1111

12-
componentWillMount() {
13-
var self = this;
14-
var quickFilters = this.context.filterBarStore.quickFilters;
15-
Object.keys(this.getStateFromStores().filters).map(function(filterUid) {
16-
Object.keys(quickFilters).map(function(blockName) {
17-
Object.keys(quickFilters[blockName]).map(function(filterName) {
18-
var quickFilter = quickFilters[blockName][filterName];
19-
if (quickFilter.filters && quickFilter.filters[filterUid]) {
20-
if (self.getStateFromStores().filters[filterUid].type == 'multi_select') {
21-
if (self.getStateFromStores().filters[filterUid].value.join(",") === quickFilter.filters[filterUid].value)
22-
quickFilter.active = true;
23-
} else {
24-
if (self.getStateFromStores().filters[filterUid].value === quickFilter.filters[filterUid].value) {
25-
quickFilter.active = true;
26-
}
27-
}
28-
}
29-
});
30-
});
31-
});
32-
this.context.filterBarStore.addChangeListener(this.onChange.bind(this));
12+
componentDidMount() {
13+
// TODO: Potential memory leak issue
14+
// https://github.com/facebook/react/issues/6266#issuecomment-196998237
15+
this.onChange = this.onChange.bind(this);
16+
this.context.filterBarStore.addChangeListener(this.onChange);
3317
}
3418

3519
onChange() {
3620
this.setState(this.getStateFromStores());
3721
}
3822

23+
onFilterRemove(groupKey, inputKey) {
24+
this.context.filterBarActor.clearActiveFilter(groupKey, inputKey);
25+
}
26+
27+
onButtonClick(filterUid, groupKey) {
28+
this.context.filterBarStore.addGroupFilter(filterUid, groupKey);
29+
}
30+
3931
getStateFromStores() {
4032
return {
41-
filters: this.context.filterBarStore.getEnabled()
33+
filters: this.context.filterBarStore.getActiveFilters()
4234
};
4335
}
4436

@@ -51,45 +43,60 @@ export class FilterDisplay extends React.Component {
5143
}
5244

5345
addGroup(filterUid) {
54-
this.context.filterBarStore.addGroupFilter(-1, filterUid);
46+
this.context.filterBarStore.addGroupFilter(filterUid);
5547
}
5648

5749
render() {
58-
var filters = [];
59-
this.getActiveFilters().map(function(groupFilters, idx) {
50+
const filters = []
51+
const ctrl = this;
52+
53+
this.state.filters.map(function(groupFilters, idx) {
6054
if (idx > 0) {
6155
filters.push(
6256
(
63-
<div style={ { marginTop: 'auto', marginBottom: 'auto', padding: '10px'} }>OR</div>
57+
<div
58+
key={ Math.random() }
59+
style={ { marginTop: 'auto', marginBottom: 'auto', padding: '10px'} }
60+
>OR</div>
6461
)
6562
)
6663
}
6764

6865
filters.push(
6966
(<FilterGroup
70-
key={ idx }
67+
key={ Math.random() }
7168
groupKey={ idx }
7269
filters={ groupFilters }
70+
onFilterRemove={ ctrl.onFilterRemove.bind(ctrl) }
71+
onButtonClick={ ctrl.onButtonClick.bind(ctrl) }
7372
/>)
7473
);
7574

7675
})
7776

7877
if (filters.length === 0) {
7978
filters.push((
80-
<div style={ { marginTop: 'auto', marginBottom: 'auto', padding: '10px'} }>
79+
<div
80+
style={ { marginTop: 'auto', marginBottom: 'auto', padding: '10px'} }
81+
key={ Math.random() }
82+
>
8183
<FilterButton
82-
filters={ this.getFilters() }
83-
title="ADD FILTER"
84-
onClick={ this.addGroup.bind(this) }
84+
key={ Math.random() }
85+
filters={ this.getFilters() }
86+
title="ADD FILTER"
87+
onClick={ this.addGroup.bind(this) }
8588
/>
8689
</div>)
8790
);
8891
} else {
8992
filters.push(
9093
(
91-
<div style={ { marginTop: 'auto', marginBottom: 'auto', padding: '10px'} }>
94+
<div
95+
style={ { marginTop: 'auto', marginBottom: 'auto', padding: '10px'} }
96+
key={ Math.random() }
97+
>
9298
<FilterButton
99+
key={ Math.random() }
93100
filters={ this.getFilters() }
94101
title="OR"
95102
onClick={ this.addGroup.bind(this) }
@@ -111,11 +118,11 @@ export class FilterDisplay extends React.Component {
111118
}
112119

113120
FilterDisplay.propTypes = {
114-
enabledFilters: React.PropTypes.object.isRequired
121+
filters: React.PropTypes.array.isRequired
115122
};
116123

117124
FilterDisplay.defaultProps = {
118-
enabledFilters: {}
125+
filters: []
119126
};
120127

121128
FilterDisplay.contextTypes = {

0 commit comments

Comments
 (0)