Skip to content

Commit

Permalink
loans: date range search
Browse files Browse the repository at this point in the history
- filters  loans_from_date and loans_to_date on loan start date
- datepickers for ui
- depends on react-searchkit release 0.18.0
- closes #168
  • Loading branch information
topless committed Apr 1, 2020
1 parent 6da7d71 commit 7e4ca5d
Show file tree
Hide file tree
Showing 6 changed files with 101 additions and 9 deletions.
7 changes: 5 additions & 2 deletions invenio_app_ils/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,9 @@
from .documents.api import DOCUMENT_PID_FETCHER, DOCUMENT_PID_MINTER, \
DOCUMENT_PID_TYPE, Document
from .documents.search import DocumentSearch
from .facets import default_value_when_missing_filter, keyed_range_filter, \
not_empty_object_or_list_filter, overdue_agg, overdue_loans_filter
from .facets import date_range_filter, default_value_when_missing_filter, \
keyed_range_filter, not_empty_object_or_list_filter, overdue_agg, \
overdue_loans_filter
from .records.views import UserInfoResource

from .api import ( # isort:skip
Expand Down Expand Up @@ -1191,6 +1192,8 @@ def _(x):
),
filters={
"returns.end_date": overdue_loans_filter("end_date"),
"loans_from_date": date_range_filter("start_date", "gte"),
"loans_to_date": date_range_filter("start_date", "lte"),
},
post_filters=dict(
state=terms_filter("state"),
Expand Down
12 changes: 11 additions & 1 deletion invenio_app_ils/facets.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
# it under the terms of the MIT License; see LICENSE file for more details.

"""Facets and factories for result filtering and aggregation."""
from datetime import timedelta

import arrow
from elasticsearch_dsl.query import Bool, Q, Range
Expand Down Expand Up @@ -113,3 +112,14 @@ def overdue_agg():
)
)
)


def date_range_filter(field, comparator):
"""Create a range filter.
:param field: Field name.
:param comparator: Comparison we want with the supplied date.
"""
def inner(values):
return Range(**{field: {comparator: str(arrow.get(values[0]).date())}})
return inner
6 changes: 3 additions & 3 deletions ui/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion ui/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
"react-router-dom": "^5.1.2",
"react-scripts": "^3.4.0",
"react-scroll": "^1.7.16",
"react-searchkit": "^0.16.0",
"react-searchkit": "^0.18.0",
"react-show-more": "^2.0.0",
"react-tagcloud": "^2.0.0",
"redux": "^4.0.4",
Expand Down
6 changes: 4 additions & 2 deletions ui/src/pages/backoffice/Loan/LoanSearch/LoanSearch.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,11 @@ import {
SearchAggregationsCards,
} from '@components/SearchControls';

import { SearchDateRange } from './SearchDateRange';

export class LoanSearch extends Component {
searchApi = new InvenioSearchApi({
url: loanApi.searchBaseURL,
withCredentials: true,
axios: { url: loanApi.searchBaseURL, withCredentials: true },
interceptors: {
response: { reject: responseRejectInterceptor },
},
Expand Down Expand Up @@ -87,6 +88,7 @@ export class LoanSearch extends Component {
<Grid.Column width={3} className={'search-aggregations'}>
<Header content={'Filter by'} />
<SearchAggregationsCards modelName={'loans'} />
<SearchDateRange />
</Grid.Column>
<Grid.Column width={13}>
<SearchEmptyResults extras={this.renderEmptyResultsExtra} />
Expand Down
77 changes: 77 additions & 0 deletions ui/src/pages/backoffice/Loan/LoanSearch/SearchDateRange.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
import React, { Component } from 'react';
import { Card } from 'semantic-ui-react';
import { DatePicker } from '@components';
import { withState } from 'react-searchkit';
import _isEmpty from 'lodash/isEmpty';

class _SearchDateRange extends Component {
getCurrentDates() {
const { filters } = this.props.currentQueryState;
let loans_from_date = '';
let loans_to_date = '';

filters.forEach(([name, value]) => {
if (name === 'loans_from_date') loans_from_date = value;
if (name === 'loans_to_date') loans_to_date = value;
});
return [loans_from_date, loans_to_date];
}

onDateChange = newFilter => {
const [name, value] = newFilter;
let result = newFilter;

if (_isEmpty(value)) {
this.props.updateQueryState({ filters: result });
return;
}

const { filters } = this.props.currentQueryState;
const existingFilters = filters.filter(filter => filter[0] === name);

if (!_isEmpty(existingFilters)) {
result = existingFilters.push(newFilter);
}
// NOTE: react-searchkit allows having the same filter multiple times.
// For the range dates filters we want each filter one time only so we have
// to we have to add also the existing filters we want to remove.
this.props.updateQueryState({ filters: result });
};

render() {
const [fromDate, toDate] = this.getCurrentDates();

return (
<Card>
<Card.Content>
<Card.Header>Date</Card.Header>
<Card.Meta>
<span>*Loan start date</span>
</Card.Meta>
</Card.Content>
<Card.Content>
<DatePicker
maxDate={toDate}
defaultValue={fromDate}
placeholder="From"
handleDateChange={value =>
this.onDateChange(['loans_from_date', value])
}
/>
</Card.Content>
<Card.Content>
<DatePicker
minDate={fromDate}
defaultValue={toDate}
placeholder="To"
handleDateChange={value =>
this.onDateChange(['loans_to_date', value])
}
/>
</Card.Content>
</Card>
);
}
}

export const SearchDateRange = withState(_SearchDateRange);

0 comments on commit 7e4ca5d

Please sign in to comment.