Skip to content

Commit

Permalink
Merge pull request #635 from SamR1/override-gpx-title
Browse files Browse the repository at this point in the history
Add ability to replace gpx title when adding a workout
  • Loading branch information
SamR1 authored Oct 6, 2024
2 parents b8e1a06 + eb592c6 commit 4a039ab
Show file tree
Hide file tree
Showing 11 changed files with 149 additions and 95 deletions.
4 changes: 2 additions & 2 deletions fittrackee/dist/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,11 @@
<link rel="stylesheet" href="/static/css/fork-awesome.min.css"/>
<link rel="stylesheet" href="/static/css/leaflet.css"/>
<title>FitTrackee</title>
<script type="module" crossorigin src="/static/index-BROICLJS.js"></script>
<script type="module" crossorigin src="/static/index-DuUOrRe4.js"></script>
<link rel="modulepreload" crossorigin href="/static/charts-lWJH0bM4.js">
<link rel="modulepreload" crossorigin href="/static/maps-BFpqWvfo.js">
<link rel="stylesheet" crossorigin href="/static/css/maps-HupOsEJb.css">
<link rel="stylesheet" crossorigin href="/static/css/index-G9nqqDAl.css">
<link rel="stylesheet" crossorigin href="/static/css/index-nH9XMQiq.css">
</head>
<body>
<div id="app"></div>
Expand Down

Large diffs are not rendered by default.

Large diffs are not rendered by default.

30 changes: 30 additions & 0 deletions fittrackee/tests/workouts/test_workouts_api_1_post.py
Original file line number Diff line number Diff line change
Expand Up @@ -481,6 +481,36 @@ def test_it_adds_a_workout_with_gpx_without_name(
)
assert_workout_data_with_gpx(data)

def test_it_adds_a_workout_with_provided_title(
self,
app: Flask,
user_1: User,
sport_1_cycling: Sport,
gpx_file: str,
) -> None:
title = "some title"
client, auth_token = self.get_test_client_and_auth_token(
app, user_1.email
)

response = client.post(
'/api/workouts',
data=dict(
file=(BytesIO(str.encode(gpx_file)), 'example.gpx'),
data=f'{{"sport_id": 1, "title": "{title}"}}',
),
headers=dict(
content_type='multipart/form-data',
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]['title'] == title

def test_it_adds_a_workout_with_gpx_without_name_timezone(
self,
app: Flask,
Expand Down
8 changes: 7 additions & 1 deletion fittrackee/workouts/utils/workouts.py
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,13 @@ def create_workout(
else timedelta(seconds=workout_data['duration'])
)
distance = gpx_data['distance'] if gpx_data else workout_data['distance']
title = gpx_data['name'] if gpx_data else workout_data.get('title', '')
title = (
workout_data.get('title', '')
if workout_data.get('title', '')
else gpx_data['name']
if gpx_data
else ''
)

new_workout = Workout(
user_id=user.id,
Expand Down
17 changes: 10 additions & 7 deletions fittrackee/workouts/workouts.py
Original file line number Diff line number Diff line change
Expand Up @@ -1043,21 +1043,24 @@ def post_workout(auth_user: User) -> Union[Tuple[Dict, int], HttpResponse]:
}
:form file: gpx file (allowed extensions: .gpx, .zip)
:form data: sport id, equipment id, description and notes, for example:
`{"sport_id": 1, "notes": "", "description": "", "equipment_ids": []}`.
Double quotes in notes and description must be escaped.
:form data: sport id, equipment id, description, title and notes,
for example:
``{"sport_id": 1, "notes": "", "title": "", "description": "",
"equipment_ids": []}``.
Double quotes in notes, description and title must be escaped.
The maximum length of notes is 500 characters and that of the
description is 10000 characters.
Otherwise, they will be truncated.
The maximum length is 500 characters for notes, 10000 characters for
description and 255 for title. Otherwise, they will be truncated.
When description and title are provided, they replace the description
and title from gpx file.
For `equipment_ids`, the id of the equipment to associate with
this workout.
**Note**: for now only one equipment can be associated.
If not provided and default equipment exists for sport,
default equipment will be associated.
Notes, description and equipment ids are not mandatory.
Notes, description, and title and equipment ids are not mandatory.
:reqheader Authorization: OAuth 2.0 Bearer Token
Expand Down
26 changes: 19 additions & 7 deletions fittrackee_client/src/components/Workout/WorkoutEdition.vue
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@
</div>
</div>
</div>
<div class="form-item" v-else>
<div class="form-item">
<label for="title"> {{ $t('workouts.TITLE') }}: </label>
<input
id="title"
Expand All @@ -105,6 +105,12 @@
v-model="workoutForm.title"
maxlength="255"
/>
<div class="filed-help" v-if="withGpx && isCreation">
<span class="info-box">
<i class="fa fa-info-circle" aria-hidden="true" />
{{ $t('workouts.TITLE_FIELD_HELP') }}
</span>
</div>
</div>
<div v-if="!withGpx">
<div class="workout-date-duration">
Expand Down Expand Up @@ -512,7 +518,6 @@
}
function formatPayload(payload: IWorkoutForm) {
payloadErrorMessages.value = []
payload.title = workoutForm.title
payload.duration =
+workoutForm.workoutDurationHour * 3600 +
+workoutForm.workoutDurationMinutes * 60 +
Expand Down Expand Up @@ -556,11 +561,10 @@
equipmentsForSelect.value.find((e) => e.id === workoutForm.equipment_id)
? [workoutForm.equipment_id]
: [],
title: workoutForm.title,
}
if (props.workout.id) {
if (props.workout.with_gpx) {
payload.title = workoutForm.title
} else {
if (!props.workout.with_gpx) {
formatPayload(payload)
}
if (payloadErrorMessages.value.length > 0) {
Expand Down Expand Up @@ -677,7 +681,8 @@
.form-item {
display: flex;
flex-direction: column;
padding: $default-padding;
padding: $default-padding * 0.5 $default-padding $default-padding *
0.25;
.workout-date-time {
display: flex;
Expand Down Expand Up @@ -710,15 +715,17 @@
.form-buttons {
display: flex;
justify-content: flex-end;
padding: $default-padding $default-padding * 0.5 0;
button {
margin: $default-padding * 0.5;
margin: $default-margin * 0.5;
}
}
.files-help {
display: flex;
justify-content: space-around;
margin-top: $default-margin;
padding: $default-padding * 0.75 $default-padding;
div {
display: flex;
@media screen and (max-width: $medium-limit) {
Expand All @@ -731,6 +738,11 @@
}
}
.filed-help {
display: flex;
margin-top: $default-margin * 0.5;
}
.workout-data {
display: flex;
flex-direction: row;
Expand Down
1 change: 1 addition & 0 deletions fittrackee_client/src/locales/en/workouts.json
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@
"START_AND_FINISH": "Start and finish",
"START_ELEVATION_AT_ZERO": "start elevation axis at zero",
"TITLE": "title",
"TITLE_FIELD_HELP": "if provided, the title replaces that of the gpx file.",
"TO": "to",
"TOTAL_DISTANCE": "total distance",
"TOTAL_DURATION": "total duration",
Expand Down
1 change: 1 addition & 0 deletions fittrackee_client/src/locales/fr/workouts.json
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@
"START_AND_FINISH": "Départ et arrivée",
"START_ELEVATION_AT_ZERO": "démarrer l'axe de l'altitude à 0",
"TITLE": "titre",
"TITLE_FIELD_HELP": "si fourni, le titre remplace celui du fichier gpx.",
"TO": "jusqu'au",
"TOTAL_DISTANCE": "distance totale",
"TOTAL_DURATION": "durée totale",
Expand Down
3 changes: 2 additions & 1 deletion fittrackee_client/src/store/modules/workouts/actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -218,12 +218,13 @@ export const actions: ActionTree<IWorkoutsState, IRootState> &
}
const notes = payload.notes.replace(/"/g, '\\"')
const description = payload.description.replace(/"/g, '\\"')
const title = payload.title.replace(/"/g, '\\"')
const form = new FormData()
form.append('file', payload.file)
form.append(
'data',
`{"sport_id": ${payload.sport_id}, "notes": "${notes}",` +
` "description": "${description}",` +
` "description": "${description}", "title": "${title}", ` +
` "equipment_ids": [${payload.equipment_ids.map((e) => `"${e}"`).join(',')}]}`
)
authApi
Expand Down
2 changes: 1 addition & 1 deletion fittrackee_client/src/types/workouts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ export interface IWorkoutObject {
export interface IWorkoutForm {
sport_id: number | null
notes: string
title?: string
title: string
workout_date?: string
distance?: number
duration?: number
Expand Down

0 comments on commit 4a039ab

Please sign in to comment.