API & Client: filter activities - #3 (WIP)
This commit is contained in:
parent
479b47455f
commit
f45db7b969
@ -33,9 +33,11 @@ def get_activities(auth_user_id):
|
|||||||
ave_speed_from = params.get('ave_speed_from')
|
ave_speed_from = params.get('ave_speed_from')
|
||||||
ave_speed_to = params.get('ave_speed_to')
|
ave_speed_to = params.get('ave_speed_to')
|
||||||
order = params.get('order')
|
order = params.get('order')
|
||||||
|
sport_id = params.get('sport_id')
|
||||||
per_page = int(params.get('per_page')) if params.get('per_page') else 5
|
per_page = int(params.get('per_page')) if params.get('per_page') else 5
|
||||||
activities = Activity.query.filter(
|
activities = Activity.query.filter(
|
||||||
Activity.user_id == auth_user_id,
|
Activity.user_id == auth_user_id,
|
||||||
|
Activity.sport_id == sport_id if sport_id else True,
|
||||||
Activity.activity_date >= datetime.strptime(date_from, '%Y-%m-%d')
|
Activity.activity_date >= datetime.strptime(date_from, '%Y-%m-%d')
|
||||||
if date_from else True,
|
if date_from else True,
|
||||||
Activity.activity_date <= datetime.strptime(date_to, '%Y-%m-%d')
|
Activity.activity_date <= datetime.strptime(date_to, '%Y-%m-%d')
|
||||||
|
@ -487,6 +487,35 @@ def test_get_activities_ave_speed_filter(
|
|||||||
assert 'Fri, 23 Feb 2018 00:00:00 GMT' == data['data']['activities'][0]['activity_date'] # noqa
|
assert 'Fri, 23 Feb 2018 00:00:00 GMT' == data['data']['activities'][0]['activity_date'] # noqa
|
||||||
|
|
||||||
|
|
||||||
|
def test_get_activities_sport_filter(
|
||||||
|
app, user_1, sport_1_cycling, seven_activities_user_1, sport_2_running,
|
||||||
|
activity_running_user_1
|
||||||
|
):
|
||||||
|
client = app.test_client()
|
||||||
|
resp_login = client.post(
|
||||||
|
'/api/auth/login',
|
||||||
|
data=json.dumps(dict(
|
||||||
|
email='test@test.com',
|
||||||
|
password='12345678'
|
||||||
|
)),
|
||||||
|
content_type='application/json'
|
||||||
|
)
|
||||||
|
response = client.get(
|
||||||
|
'/api/activities?sport_id=2',
|
||||||
|
headers=dict(
|
||||||
|
Authorization='Bearer ' + json.loads(
|
||||||
|
resp_login.data.decode()
|
||||||
|
)['auth_token']
|
||||||
|
)
|
||||||
|
)
|
||||||
|
data = json.loads(response.data.decode())
|
||||||
|
|
||||||
|
assert response.status_code == 200
|
||||||
|
assert 'success' in data['status']
|
||||||
|
assert len(data['data']['activities']) == 1
|
||||||
|
assert 'Sun, 01 Apr 2018 00:00:00 GMT' == data['data']['activities'][0]['activity_date'] # noqa
|
||||||
|
|
||||||
|
|
||||||
def test_get_an_activity(
|
def test_get_an_activity(
|
||||||
app, user_1, sport_1_cycling, activity_cycling_user_1
|
app, user_1, sport_1_cycling, activity_cycling_user_1
|
||||||
):
|
):
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import React from 'react'
|
import React from 'react'
|
||||||
|
|
||||||
export default function ActivitiesList (props) {
|
export default function ActivitiesList (props) {
|
||||||
const { sports } = props
|
const { loadActivities, sports, updateParams } = props
|
||||||
return (
|
return (
|
||||||
<div className="card">
|
<div className="card">
|
||||||
<div className="card-body activity-filter">
|
<div className="card-body activity-filter">
|
||||||
@ -10,16 +10,18 @@ export default function ActivitiesList (props) {
|
|||||||
<label>
|
<label>
|
||||||
From:
|
From:
|
||||||
<input
|
<input
|
||||||
name="start"
|
|
||||||
className="form-control col-md"
|
className="form-control col-md"
|
||||||
|
name="from"
|
||||||
|
onChange={e => updateParams(e)}
|
||||||
type="date"
|
type="date"
|
||||||
/>
|
/>
|
||||||
</label>
|
</label>
|
||||||
<label>
|
<label>
|
||||||
To:
|
To:
|
||||||
<input
|
<input
|
||||||
name="end"
|
|
||||||
className="form-control col-md"
|
className="form-control col-md"
|
||||||
|
name="to"
|
||||||
|
onChange={e => updateParams(e)}
|
||||||
type="date"
|
type="date"
|
||||||
/>
|
/>
|
||||||
</label>
|
</label>
|
||||||
@ -30,6 +32,7 @@ export default function ActivitiesList (props) {
|
|||||||
<select
|
<select
|
||||||
className="form-control input-lg"
|
className="form-control input-lg"
|
||||||
name="sport_id"
|
name="sport_id"
|
||||||
|
onChange={e => updateParams(e)}
|
||||||
>
|
>
|
||||||
<option value="" />
|
<option value="" />
|
||||||
{sports.map(sport => (
|
{sports.map(sport => (
|
||||||
@ -47,9 +50,10 @@ export default function ActivitiesList (props) {
|
|||||||
<div className="row">
|
<div className="row">
|
||||||
<div className="col-5">
|
<div className="col-5">
|
||||||
<input
|
<input
|
||||||
name="distance-from"
|
|
||||||
className="form-control"
|
className="form-control"
|
||||||
min={0}
|
min={0}
|
||||||
|
name="distance_from"
|
||||||
|
onChange={e => updateParams(e)}
|
||||||
step="1"
|
step="1"
|
||||||
type="number"
|
type="number"
|
||||||
/>
|
/>
|
||||||
@ -57,9 +61,10 @@ export default function ActivitiesList (props) {
|
|||||||
<div className="col-2 align-middle text-center">to</div>
|
<div className="col-2 align-middle text-center">to</div>
|
||||||
<div className="col-5">
|
<div className="col-5">
|
||||||
<input
|
<input
|
||||||
name="distance-to"
|
|
||||||
className="form-control"
|
className="form-control"
|
||||||
min={0}
|
min={0}
|
||||||
|
name="distance_to"
|
||||||
|
onChange={e => updateParams(e)}
|
||||||
step="1"
|
step="1"
|
||||||
type="number"
|
type="number"
|
||||||
/>
|
/>
|
||||||
@ -75,8 +80,9 @@ export default function ActivitiesList (props) {
|
|||||||
<div className="row">
|
<div className="row">
|
||||||
<div className="col-5">
|
<div className="col-5">
|
||||||
<input
|
<input
|
||||||
name="duration-from"
|
|
||||||
className="form-control"
|
className="form-control"
|
||||||
|
name="duration_from"
|
||||||
|
onChange={e => updateParams(e)}
|
||||||
pattern="^([0-9]*[0-9]):([0-5][0-9])$"
|
pattern="^([0-9]*[0-9]):([0-5][0-9])$"
|
||||||
placeholder="hh:mm"
|
placeholder="hh:mm"
|
||||||
type="text"
|
type="text"
|
||||||
@ -85,8 +91,9 @@ export default function ActivitiesList (props) {
|
|||||||
<div className="col-2 align-middle text-center">to</div>
|
<div className="col-2 align-middle text-center">to</div>
|
||||||
<div className="col-5">
|
<div className="col-5">
|
||||||
<input
|
<input
|
||||||
name="duration-to"
|
|
||||||
className="form-control"
|
className="form-control"
|
||||||
|
name="duration_to"
|
||||||
|
onChange={e => updateParams(e)}
|
||||||
pattern="^([0-9]*[0-9]):([0-5][0-9])$"
|
pattern="^([0-9]*[0-9]):([0-5][0-9])$"
|
||||||
placeholder="hh:mm"
|
placeholder="hh:mm"
|
||||||
type="text"
|
type="text"
|
||||||
@ -103,9 +110,10 @@ export default function ActivitiesList (props) {
|
|||||||
<div className="row">
|
<div className="row">
|
||||||
<div className="col-5">
|
<div className="col-5">
|
||||||
<input
|
<input
|
||||||
name="speed-from"
|
|
||||||
className="form-control"
|
className="form-control"
|
||||||
min={0}
|
min={0}
|
||||||
|
name="ave_speed_from"
|
||||||
|
onChange={e => updateParams(e)}
|
||||||
step="1"
|
step="1"
|
||||||
type="number"
|
type="number"
|
||||||
/>
|
/>
|
||||||
@ -113,9 +121,10 @@ export default function ActivitiesList (props) {
|
|||||||
<div className="col-2 align-middle text-center">to</div>
|
<div className="col-2 align-middle text-center">to</div>
|
||||||
<div className="col-5">
|
<div className="col-5">
|
||||||
<input
|
<input
|
||||||
name="speed-to"
|
|
||||||
className="form-control"
|
className="form-control"
|
||||||
min={0}
|
min={0}
|
||||||
|
name="ave_speed_to"
|
||||||
|
onChange={e => updateParams(e)}
|
||||||
step="1"
|
step="1"
|
||||||
type="number"
|
type="number"
|
||||||
/>
|
/>
|
||||||
@ -125,8 +134,9 @@ export default function ActivitiesList (props) {
|
|||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
<input
|
<input
|
||||||
type="submit"
|
|
||||||
className="btn btn-primary btn-lg btn-block"
|
className="btn btn-primary btn-lg btn-block"
|
||||||
|
onClick={() => loadActivities()}
|
||||||
|
type="submit"
|
||||||
value="Filter"
|
value="Filter"
|
||||||
/>
|
/>
|
||||||
</form>
|
</form>
|
||||||
|
@ -12,17 +12,32 @@ class Activities extends React.Component {
|
|||||||
constructor(props, context) {
|
constructor(props, context) {
|
||||||
super(props, context)
|
super(props, context)
|
||||||
this.state = {
|
this.state = {
|
||||||
|
params: {
|
||||||
page: 1,
|
page: 1,
|
||||||
|
per_page: 10,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
this.props.loadActivities()
|
this.props.loadActivities(this.state.params)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setParams(e) {
|
||||||
|
const { params } = this.state
|
||||||
|
if (e.target.value === '') {
|
||||||
|
delete params[e.target.name]
|
||||||
|
} else {
|
||||||
|
params[e.target.name] = e.target.value
|
||||||
|
}
|
||||||
|
params.page = 1
|
||||||
|
this.setState(params)
|
||||||
|
}
|
||||||
render() {
|
render() {
|
||||||
const { activities, loadMoreActivities, message, sports } = this.props
|
const {
|
||||||
const { page } = this.state
|
activities, loadActivities, loadMoreActivities, message, sports
|
||||||
|
} = this.props
|
||||||
|
const { params } = this.state
|
||||||
const paginationEnd = activities.length > 0
|
const paginationEnd = activities.length > 0
|
||||||
? activities[activities.length - 1].previous_activity === null
|
? activities[activities.length - 1].previous_activity === null
|
||||||
: true
|
: true
|
||||||
@ -39,6 +54,8 @@ class Activities extends React.Component {
|
|||||||
<div className="col-md-3">
|
<div className="col-md-3">
|
||||||
<ActivitiesFilter
|
<ActivitiesFilter
|
||||||
sports={sports}
|
sports={sports}
|
||||||
|
loadActivities={() => loadActivities(params)}
|
||||||
|
updateParams={e => this.setParams(e)}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="col-md-9">
|
<div className="col-md-9">
|
||||||
@ -52,8 +69,9 @@ class Activities extends React.Component {
|
|||||||
className="btn btn-default btn-md btn-block"
|
className="btn btn-default btn-md btn-block"
|
||||||
value="Load more activities"
|
value="Load more activities"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
loadMoreActivities(page + 1)
|
params.page += 1
|
||||||
this.setState({ page: page + 1 })
|
loadMoreActivities(params)
|
||||||
|
this.setState(params)
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
@ -73,12 +91,11 @@ export default connect(
|
|||||||
sports: state.sports.data,
|
sports: state.sports.data,
|
||||||
}),
|
}),
|
||||||
dispatch => ({
|
dispatch => ({
|
||||||
loadActivities: () => {
|
loadActivities: params => {
|
||||||
dispatch(getData('activities', { page: 1, per_page: 10 }))
|
dispatch(getData('activities', params))
|
||||||
dispatch(getData('records'))
|
|
||||||
},
|
},
|
||||||
loadMoreActivities: page => {
|
loadMoreActivities: params => {
|
||||||
dispatch(getMoreActivities({ page, per_page: 10 }))
|
dispatch(getMoreActivities(params))
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
)(Activities)
|
)(Activities)
|
||||||
|
Loading…
Reference in New Issue
Block a user