Merge pull request #408 from SamR1/fix-workout-display

Fix workout display when speeds are zero
This commit is contained in:
Sam 2023-07-29 18:26:58 +02:00 committed by GitHub
commit a1888c51ce
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
19 changed files with 80 additions and 37 deletions

View File

@ -1 +1 @@
<!doctype html><html lang="en"><head><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width,initial-scale=1"><!--[if IE]><link rel="icon" href="/favicon.ico"><![endif]--><link rel="stylesheet" href="/static/css/fork-awesome.min.css"/><link rel="stylesheet" href="/static/css/leaflet.css"/><title>FitTrackee</title><script defer="defer" src="/static/js/chunk-vendors.89f4a527.js"></script><script defer="defer" src="/static/js/app.569b3ca4.js"></script><link href="/static/css/app.ac01ece3.css" rel="stylesheet"><link rel="icon" type="image/png" sizes="32x32" href="/img/icons/favicon-32x32.png"><link rel="icon" type="image/png" sizes="16x16" href="/img/icons/favicon-16x16.png"><link rel="manifest" href="/manifest.json"><meta name="theme-color" content="#4DBA87"><meta name="apple-mobile-web-app-capable" content="no"><meta name="apple-mobile-web-app-status-bar-style" content="default"><meta name="apple-mobile-web-app-title" content="fittrackee_client"><link rel="apple-touch-icon" href="/img/icons/apple-touch-icon-152x152.png"><link rel="mask-icon" href="/img/icons/safari-pinned-tab.svg" color="#4DBA87"><meta name="msapplication-TileImage" content="/img/icons/msapplication-icon-144x144.png"><meta name="msapplication-TileColor" content="#000000"></head><body><noscript><strong>We're sorry but FitTrackee doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript><div id="app"></div></body></html> <!doctype html><html lang="en"><head><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width,initial-scale=1"><!--[if IE]><link rel="icon" href="/favicon.ico"><![endif]--><link rel="stylesheet" href="/static/css/fork-awesome.min.css"/><link rel="stylesheet" href="/static/css/leaflet.css"/><title>FitTrackee</title><script defer="defer" src="/static/js/chunk-vendors.89f4a527.js"></script><script defer="defer" src="/static/js/app.b0d58ef5.js"></script><link href="/static/css/app.ac01ece3.css" rel="stylesheet"><link rel="icon" type="image/png" sizes="32x32" href="/img/icons/favicon-32x32.png"><link rel="icon" type="image/png" sizes="16x16" href="/img/icons/favicon-16x16.png"><link rel="manifest" href="/manifest.json"><meta name="theme-color" content="#4DBA87"><meta name="apple-mobile-web-app-capable" content="no"><meta name="apple-mobile-web-app-status-bar-style" content="default"><meta name="apple-mobile-web-app-title" content="fittrackee_client"><link rel="apple-touch-icon" href="/img/icons/apple-touch-icon-152x152.png"><link rel="mask-icon" href="/img/icons/safari-pinned-tab.svg" color="#4DBA87"><meta name="msapplication-TileImage" content="/img/icons/msapplication-icon-144x144.png"><meta name="msapplication-TileColor" content="#000000"></head><body><noscript><strong>We're sorry but FitTrackee doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript><div id="app"></div></body></html>

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1132,6 +1132,39 @@ class TestPostWorkoutWithoutGpx(ApiTestCaseMixin):
assert data['data']['workouts'][0]['ascent'] == input_ascent assert data['data']['workouts'][0]['ascent'] == input_ascent
assert data['data']['workouts'][0]['descent'] == input_descent assert data['data']['workouts'][0]['descent'] == input_descent
def test_it_adds_workout_with_low_value_for_distance(
self,
app: Flask,
user_1: User,
sport_1_cycling: Sport,
) -> None:
client, auth_token = self.get_test_client_and_auth_token(
app, user_1.email
)
response = client.post(
'/api/workouts/no_gpx',
content_type='application/json',
data=json.dumps(
dict(
sport_id=1,
duration=1200,
workout_date='2023-07-26 12:00',
distance=0.001,
)
),
headers=dict(Authorization=f'Bearer {auth_token}'),
)
data = json.loads(response.data.decode())
assert response.status_code == 201
assert 'created' in data['status']
assert len(data['data']['workouts']) == 1
assert data['data']['workouts'][0]['ave_speed'] == 0
assert data['data']['workouts'][0]['distance'] == 0.001
assert data['data']['workouts'][0]['duration'] == '0:20:00'
assert data['data']['workouts'][0]['max_speed'] == 0
@pytest.mark.parametrize( @pytest.mark.parametrize(
'description,input_data', 'description,input_data',
[ [

View File

@ -200,18 +200,22 @@ class Workout(BaseModel):
'creation_date': self.creation_date, 'creation_date': self.creation_date,
'modification_date': self.modification_date, 'modification_date': self.modification_date,
'workout_date': self.workout_date, 'workout_date': self.workout_date,
'duration': str(self.duration) if self.duration else None, 'duration': None if self.duration is None else str(self.duration),
'pauses': str(self.pauses) if self.pauses else None, 'pauses': str(self.pauses) if self.pauses else None,
'moving': str(self.moving) if self.moving else None, 'moving': None if self.moving is None else str(self.moving),
'distance': float(self.distance) if self.distance else None, 'distance': (
'min_alt': float(self.min_alt) if self.min_alt else None, None if self.distance is None else float(self.distance)
'max_alt': float(self.max_alt) if self.max_alt else None, ),
'descent': float(self.descent) 'min_alt': None if self.min_alt is None else float(self.min_alt),
if self.descent is not None 'max_alt': None if self.max_alt is None else float(self.max_alt),
else None, 'descent': None if self.descent is None else float(self.descent),
'ascent': float(self.ascent) if self.ascent is not None else None, 'ascent': None if self.ascent is None else float(self.ascent),
'max_speed': float(self.max_speed) if self.max_speed else None, 'max_speed': (
'ave_speed': float(self.ave_speed) if self.ave_speed else None, None if self.max_speed is None else float(self.max_speed)
),
'ave_speed': (
None if self.ave_speed is None else float(self.ave_speed)
),
'records': [record.serialize() for record in self.records], 'records': [record.serialize() for record in self.records],
'segments': [segment.serialize() for segment in self.segments], 'segments': [segment.serialize() for segment in self.segments],
'weather_start': self.weather_start, 'weather_start': self.weather_start,

View File

@ -12,7 +12,7 @@
<span class="value">{{ workoutObject.duration }})</span> <span class="value">{{ workoutObject.duration }})</span>
</div> </div>
</div> </div>
<div class="workout-data"> <div class="workout-data" v-if="workoutObject.distance !== null">
<i class="fa fa-road" aria-hidden="true" /> <i class="fa fa-road" aria-hidden="true" />
<span class="label"> {{ $t('workouts.DISTANCE') }} </span>: <span class="label"> {{ $t('workouts.DISTANCE') }} </span>:
<Distance <Distance
@ -24,7 +24,10 @@
/> />
<WorkoutRecord :workoutObject="workoutObject" recordType="FD" /> <WorkoutRecord :workoutObject="workoutObject" recordType="FD" />
</div> </div>
<div class="workout-data"> <div
class="workout-data"
v-if="workoutObject.aveSpeed !== null && workoutObject.maxSpeed !== null"
>
<i class="fa fa-tachometer" aria-hidden="true" /> <i class="fa fa-tachometer" aria-hidden="true" />
<span class="label">{{ $t('workouts.AVERAGE_SPEED') }}</span <span class="label">{{ $t('workouts.AVERAGE_SPEED') }}</span
>: >:

View File

@ -98,6 +98,7 @@
{{ $t('workouts.DISTANCE') }} {{ $t('workouts.DISTANCE') }}
</span> </span>
<Distance <Distance
v-if="workout.distance !== null"
:distance="workout.distance" :distance="workout.distance"
unitFrom="km" unitFrom="km"
:useImperialUnits="user.imperial_units" :useImperialUnits="user.imperial_units"
@ -114,6 +115,7 @@
{{ $t('workouts.AVE_SPEED') }} {{ $t('workouts.AVE_SPEED') }}
</span> </span>
<Distance <Distance
v-if="workout.ave_speed !== null"
:distance="workout.ave_speed" :distance="workout.ave_speed"
unitFrom="km" unitFrom="km"
:speed="true" :speed="true"
@ -125,6 +127,7 @@
{{ $t('workouts.MAX_SPEED') }} {{ $t('workouts.MAX_SPEED') }}
</span> </span>
<Distance <Distance
v-if="workout.max_speed !== null"
:distance="workout.max_speed" :distance="workout.max_speed"
unitFrom="km" unitFrom="km"
:speed="true" :speed="true"

View File

@ -55,19 +55,19 @@ export interface IWeather {
export interface IWorkout { export interface IWorkout {
ascent: number | null ascent: number | null
ave_speed: number ave_speed: number | null
bounds: number[] bounds: number[]
creation_date: string creation_date: string
descent: number | null descent: number | null
distance: number distance: number | null
duration: string duration: string | null
id: string id: string
map: string | null map: string | null
max_alt: number | null max_alt: number | null
max_speed: number max_speed: number | null
min_alt: number | null min_alt: number | null
modification_date: string | null modification_date: string | null
moving: string moving: string | null
next_workout: string | null next_workout: string | null
notes: string notes: string
pauses: string | null pauses: string | null
@ -85,14 +85,14 @@ export interface IWorkout {
export interface IWorkoutObject { export interface IWorkoutObject {
ascent: number | null ascent: number | null
aveSpeed: number aveSpeed: number | null
descent: number | null descent: number | null
distance: number distance: number | null
duration: string duration: string | null
maxAlt: number | null maxAlt: number | null
maxSpeed: number maxSpeed: number | null
minAlt: number | null minAlt: number | null
moving: string moving: string | null
nextUrl: string | null nextUrl: string | null
pauses: string | null pauses: string | null
previousUrl: string | null previousUrl: string | null