aboutsummaryrefslogtreecommitdiff
path: root/src/web
diff options
context:
space:
mode:
Diffstat (limited to 'src/web')
-rw-r--r--src/web/js/actions/MiddlePanelActions.js15
-rw-r--r--src/web/js/components/MiddlePanel.react.js84
-rw-r--r--src/web/js/stores/MiddlePanelStore.js17
-rw-r--r--src/web/static/css/one-page-app.css7
-rw-r--r--src/web/views/views.py13
5 files changed, 127 insertions, 9 deletions
diff --git a/src/web/js/actions/MiddlePanelActions.js b/src/web/js/actions/MiddlePanelActions.js
index ab54217e..e1ced2a2 100644
--- a/src/web/js/actions/MiddlePanelActions.js
+++ b/src/web/js/actions/MiddlePanelActions.js
@@ -23,13 +23,13 @@ var shouldFetch = function(filters) {
}
var reloadIfNecessaryAndDispatch = function(dispath_payload) {
if(shouldFetch(dispath_payload)) {
- filters = MiddlePanelStore.getRequestFilter();
+ var filters = MiddlePanelStore.getRequestFilter();
for (var key in filters) {
if(dispath_payload[key] != null) {
filters[key] = dispath_payload[key];
}
}
- jquery.getJSON('/middle_panel', dispath_payload,
+ jquery.getJSON('/middle_panel', filters,
function(payload) {
dispath_payload.articles = payload.articles;
JarrDispatcher.dispatch(dispath_payload);
@@ -52,6 +52,17 @@ var MiddlePanelActions = {
});
});
},
+ search: function(search) {
+ MiddlePanelStore._datas.display_search = true;
+ MiddlePanelStore._datas.query = search.query;
+ MiddlePanelStore._datas.search_content = search.content;
+ MiddlePanelStore._datas.search_content = search.content;
+ this.reload();
+ },
+ search_off: function() {
+ MiddlePanelStore._datas.display_search = false;
+ this.reload();
+ },
removeParentFilter: function() {
reloadIfNecessaryAndDispatch({
type: ActionTypes.PARENT_FILTER,
diff --git a/src/web/js/components/MiddlePanel.react.js b/src/web/js/components/MiddlePanel.react.js
index 01c8b696..b2107383 100644
--- a/src/web/js/components/MiddlePanel.react.js
+++ b/src/web/js/components/MiddlePanel.react.js
@@ -52,12 +52,75 @@ var TableLine = React.createClass({
},
});
+var MiddlePanelSearchRow = React.createClass({
+ getInitialState: function() {
+ return {query: MiddlePanelStore._datas.query,
+ search_title: MiddlePanelStore._datas.search_title,
+ search_content: MiddlePanelStore._datas.search_content,
+ };
+ },
+ render: function() {
+ return (<Row>
+ <form onSubmit={this.launchSearch}>
+ <div className="input-group input-group-sm">
+ <span className="input-group-addon">
+ <span onClick={this.toogleSTitle}>Title</span>
+ <input id="search-title" type="checkbox"
+ onChange={this.toogleSTitle}
+ checked={this.state.search_title}
+ aria-label="Search title" />
+ </span>
+ <span className="input-group-addon">
+ <span onClick={this.toogleSContent}>Content</span>
+ <input id="search-content" type="checkbox"
+ onChange={this.toogleSContent}
+ checked={this.state.search_content}
+ aria-label="Search content" />
+ </span>
+ <input type="text" className="form-control"
+ onChange={this.setQuery}
+ placeholder="Search text" />
+ </div>
+ </form>
+ </Row>
+ );
+ },
+ setQuery: function(evnt) {
+ this.setState({query: evnt.target.value});
+ },
+ toogleSTitle: function() {
+ this.setState({search_title: !this.state.search_title},
+ this.launchSearch);
+ },
+ toogleSContent: function() {
+ this.setState({search_content: !this.state.search_content},
+ this.launchSearch);
+ },
+ launchSearch: function(evnt) {
+ if(this.state.query && (this.state.search_title
+ || this.state.search_content)) {
+ MiddlePanelActions.search({query: this.state.query,
+ title: this.state.search_title,
+ content: this.state.search_content});
+ }
+ if(evnt) {
+ evnt.preventDefault();
+ }
+ },
+});
+
var MiddlePanelFilter = React.createClass({
getInitialState: function() {
- return {filter: MiddlePanelStore._datas.filter};
+ return {filter: MiddlePanelStore._datas.filter,
+ display_search: MiddlePanelStore._datas.display_search};
},
render: function() {
- return (<Row className="show-grid">
+ var search_row = null;
+ if(this.state.display_search) {
+ search_row = <MiddlePanelSearchRow />
+ }
+ return (<div>
+ <Row className="show-grid">
<ButtonGroup>
<Button active={this.state.filter == "all"}
onMouseDown={this.setAllFilter}
@@ -67,13 +130,22 @@ var MiddlePanelFilter = React.createClass({
bsSize="small">Unread</Button>
<Button active={this.state.filter == "liked"}
onMouseDown={this.setLikedFilter}
- bsSize="small">Liked</Button>
+ bsSize="small">
+ <Glyphicon glyph="star" />
+ </Button>
+ </ButtonGroup>
+ <ButtonGroup>
+ <Button onMouseDown={this.toogleSearch} bsSize="small">
+ <Glyphicon glyph="search" />
+ </Button>
</ButtonGroup>
<ButtonGroup>
<Button onMouseDown={MiddlePanelActions.markAllAsRead}
bsSize="small">Mark all as read</Button>
</ButtonGroup>
</Row>
+ {search_row}
+ </div>
);
},
setAllFilter: function() {
@@ -88,6 +160,12 @@ var MiddlePanelFilter = React.createClass({
this.setState({filter: 'liked'});
MiddlePanelActions.setFilter('liked');
},
+ toogleSearch: function() {
+ if(this.state.display_search) {
+ MiddlePanelActions.search_off();
+ }
+ this.setState({display_search: !this.state.display_search});
+ },
});
var MiddlePanel = React.createClass({
diff --git a/src/web/js/stores/MiddlePanelStore.js b/src/web/js/stores/MiddlePanelStore.js
index bc7cee51..611808f7 100644
--- a/src/web/js/stores/MiddlePanelStore.js
+++ b/src/web/js/stores/MiddlePanelStore.js
@@ -7,14 +7,23 @@ var assign = require('object-assign');
var MiddlePanelStore = assign({}, EventEmitter.prototype, {
_datas: {filter: 'unread', articles: [],
- filter_type: null, filter_id: null},
+ filter_type: null, filter_id: null,
+ display_search: false, query: null,
+ search_title: true, search_content: false},
getAll: function() {
return this._datas;
},
getRequestFilter: function() {
- return {'filter': this._datas.filter,
- 'filter_type': this._datas.filter_type,
- 'filter_id': this._datas.filter_id};
+ var filters = {'filter': this._datas.filter,
+ 'filter_type': this._datas.filter_type,
+ 'filter_id': this._datas.filter_id,
+ };
+ if(this._datas.display_search) {
+ filters.query = this._datas.query;
+ filters.search_title = this._datas.search_title;
+ filters.search_content = this._datas.search_content;
+ };
+ return filters;
},
getArticles: function() {
var key = null;
diff --git a/src/web/static/css/one-page-app.css b/src/web/static/css/one-page-app.css
index 5a3444c2..d25e3886 100644
--- a/src/web/static/css/one-page-app.css
+++ b/src/web/static/css/one-page-app.css
@@ -80,3 +80,10 @@
margin-right: 10px;
margin-bottom: 10px;
}
+#middle-panel .btn-group:last-child {
+ margin-right: 0px;
+ float: right;
+}
+#middle-panel .input-group {
+ margin-bottom: 10px;
+}
diff --git a/src/web/views/views.py b/src/web/views/views.py
index b4833233..90836af1 100644
--- a/src/web/views/views.py
+++ b/src/web/views/views.py
@@ -234,6 +234,7 @@ from flask import jsonify
@app.route('/home2')
+@login_required
def new_home():
return render_template('home2.html')
@@ -265,6 +266,18 @@ def get_menu():
def _get_filters(in_dict):
filters = {}
+ query = in_dict.get('query')
+ if query:
+ search_title = in_dict.get('search_title') == 'true'
+ search_content = in_dict.get('search_content') == 'true'
+ if search_title:
+ filters['title__ilike'] = "%%%s%%" % query
+ if search_content:
+ filters['content__ilike'] = "%%%s%%" % query
+ if len(filters) == 0:
+ filters['title__ilike'] = "%%%s%%" % query
+ if len(filters) > 1:
+ filters = {"__or__": filters}
if in_dict.get('filter') == 'unread':
filters['readed'] = False
elif in_dict.get('filter') == 'liked':
bgstack15