Skip to content

Commit f90d6aa

Browse files
committed
API & Client - display user preferences depending on elevation service
1 parent 80d3523 commit f90d6aa

File tree

15 files changed

+120
-8
lines changed

15 files changed

+120
-8
lines changed

fittrackee/application/app_config.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,9 @@ def get_application_config() -> Union[Dict, HttpResponse]:
4848
"data": {
4949
"about": null,
5050
"admin_contact": "[email protected]",
51+
"elevation_services": {
52+
"open_elevation": false
53+
},
5154
"file_sync_limit_import": 10,
5255
"file_limit_import": 10,
5356
"global_map_workouts_limit": 10000,
@@ -107,6 +110,9 @@ def update_application_config(auth_user: User) -> Union[Dict, HttpResponse]:
107110
"data": {
108111
"about": null,
109112
"admin_contact": "[email protected]",
113+
"elevation_services": {
114+
"open_elevation": false
115+
},
110116
"file_sync_limit_import": 10,
111117
"file_limit_import": 10,
112118
"global_map_workouts_limit": 10000,

fittrackee/application/models.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,11 +56,19 @@ def is_registration_enabled(self) -> bool:
5656
def map_attribution(self) -> str:
5757
return current_app.config["TILE_SERVER"]["ATTRIBUTION"]
5858

59+
@property
60+
def elevation_services(self) -> Dict:
61+
return {
62+
"open_elevation": current_app.config["OPEN_ELEVATION_API_URL"]
63+
is not None
64+
}
65+
5966
def serialize(self) -> Dict:
6067
weather_provider = os.getenv("WEATHER_API_PROVIDER", "").lower()
6168
return {
6269
"about": self.about,
6370
"admin_contact": self.admin_contact,
71+
"elevation_services": self.elevation_services,
6472
"file_limit_import": self.file_limit_import,
6573
"file_sync_limit_import": self.file_sync_limit_import,
6674
"is_email_sending_enabled": current_app.config["CAN_SEND_EMAILS"],

fittrackee/tests/application/test_app_config_api.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,7 @@ def test_it_updates_all_config(
153153
data = json.loads(response.data.decode())
154154
assert "success" in data["status"]
155155
assert data["data"]["admin_contact"] == admin_email
156+
assert data["data"]["elevation_services"] == {"open_elevation": False}
156157
assert data["data"]["file_limit_import"] == 200
157158
assert data["data"]["file_sync_limit_import"] == 20
158159
assert data["data"]["global_map_workouts_limit"] == 7000

fittrackee/tests/application/test_app_config_model.py

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,10 @@ def test_application_config(
2525

2626
serialized_app_config = config.serialize()
2727
assert serialized_app_config["admin_contact"] == config.admin_contact
28+
assert (
29+
serialized_app_config["elevation_services"]
30+
== config.elevation_services
31+
)
2832
assert (
2933
serialized_app_config["file_limit_import"]
3034
== config.file_limit_import
@@ -152,3 +156,25 @@ def test_it_returns_global_map_workouts_limit(self, app: Flask) -> None:
152156
serialized_app_config["global_map_workouts_limit"]
153157
== global_map_workouts_limit
154158
)
159+
160+
def test_it_returns_elevation_services_when_open_elevation_is_disabled(
161+
self, app: "Flask"
162+
) -> None:
163+
config = AppConfig.query.one()
164+
165+
serialized_app_config = config.serialize()
166+
167+
assert serialized_app_config["elevation_services"] == {
168+
"open_elevation": False
169+
}
170+
171+
def test_it_returns_elevation_services_when_open_elevation_is_enabled(
172+
self, app_with_open_elevation_url: "Flask"
173+
) -> None:
174+
config = AppConfig.query.one()
175+
176+
serialized_app_config = config.serialize()
177+
178+
assert serialized_app_config["elevation_services"] == {
179+
"open_elevation": True
180+
}

fittrackee/tests/users/test_auth_api.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1495,13 +1495,13 @@ def test_it_returns_error_if_fields_are_missing(
14951495
)
14961496
def test_it_updates_user_preferences(
14971497
self,
1498-
app: Flask,
1498+
app_with_open_elevation_url: Flask,
14991499
user_1: User,
15001500
input_language: Optional[str],
15011501
expected_language: str,
15021502
) -> None:
15031503
client, auth_token = self.get_test_client_and_auth_token(
1504-
app, user_1.email
1504+
app_with_open_elevation_url, user_1.email
15051505
)
15061506

15071507
response = client.post(

fittrackee/tests/users/test_users_model.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
from time_machine import travel
1313

1414
from fittrackee import db
15+
from fittrackee.constants import MissingElevationsProcessing
1516
from fittrackee.equipments.models import Equipment
1617
from fittrackee.files import get_absolute_file_path
1718
from fittrackee.reports.models import ReportAction
@@ -311,6 +312,32 @@ def test_it_does_return_reports_info_when_user_has_admin_rights(
311312
assert serialized_user["reported_count"] == 0
312313
assert serialized_user["sanctions_count"] == 0
313314

315+
def test_it_returns_missing_elevations_processing_when_no_elevation_service_set( # noqa
316+
self, app: Flask, user_1: User
317+
) -> None:
318+
user_1.missing_elevations_processing = (
319+
MissingElevationsProcessing.OPEN_ELEVATION
320+
)
321+
serialized_user = user_1.serialize(current_user=user_1, light=False)
322+
323+
assert (
324+
serialized_user["missing_elevations_processing"]
325+
== MissingElevationsProcessing.NONE
326+
)
327+
328+
def test_it_returns_missing_elevations_processing_when_elevation_service_set( # noqa
329+
self, app_with_open_elevation_url: Flask, user_1: User
330+
) -> None:
331+
user_1.missing_elevations_processing = (
332+
MissingElevationsProcessing.OPEN_ELEVATION_SMOOTH
333+
)
334+
serialized_user = user_1.serialize(current_user=user_1, light=False)
335+
336+
assert (
337+
serialized_user["missing_elevations_processing"]
338+
== user_1.missing_elevations_processing
339+
)
340+
314341

315342
class TestUserSerializeAsAdmin(UserModelAssertMixin, ReportMixin):
316343
def test_it_returns_user_account_infos(

fittrackee/users/models.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -950,7 +950,9 @@ def serialize(
950950
else {}
951951
),
952952
"missing_elevations_processing": (
953-
self.missing_elevations_processing
953+
MissingElevationsProcessing.NONE
954+
if current_app.config["OPEN_ELEVATION_API_URL"] is None
955+
else self.missing_elevations_processing
954956
),
955957
}
956958

fittrackee_client/src/components/About.vue

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,9 @@
4646
{{ weatherProvider.name }}
4747
</a>
4848
</div>
49+
<div v-if="appConfig.elevation_services.open_elevation">
50+
{{ $t('about.ELEVATION_DATA_FROM') }} OpenElevation
51+
</div>
4952
<template v-if="appConfig.about">
5053
<p class="about-instance">{{ $t('about.ABOUT_THIS_INSTANCE') }}</p>
5154
<div v-html="convertToMarkdown(appConfig.about)" />
@@ -72,7 +75,7 @@
7275
7376
function get_weather_provider() {
7477
const weatherProvider: Record<string, string> = {}
75-
if (appConfig.value.weatherProvider === 'visualcrossing') {
78+
if (appConfig.value.weather_provider === 'visualcrossing') {
7679
weatherProvider['name'] = 'Visual Crossing'
7780
weatherProvider['url'] = 'https://www.visualcrossing.com'
7881
}

fittrackee_client/src/components/User/ProfileDisplay/UserPreferences.vue

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,15 @@
9696
)
9797
}}
9898
</dd>
99+
<div
100+
v-if="!appConfig.elevation_services.open_elevation"
101+
class="info-box missing-elevations-help"
102+
>
103+
<span>
104+
<i class="fa fa-info-circle" aria-hidden="true" />
105+
{{ $t('user.PROFILE.NO_ELEVATION_SERVICE_AVAILABLE') }}
106+
</span>
107+
</div>
99108
<dt>{{ $t('visibility_levels.WORKOUTS_VISIBILITY') }}:</dt>
100109
<dd>
101110
{{ $t(`visibility_levels.LEVELS.${user.workouts_visibility}`) }}
@@ -134,6 +143,7 @@
134143
import { computed, toRefs } from 'vue'
135144
import type { ComputedRef } from 'vue'
136145
146+
import useApp from '@/composables/useApp.ts'
137147
import useAuthUser from '@/composables/useAuthUser'
138148
import type { IAuthUserProfile } from '@/types/user'
139149
import { languageLabels } from '@/utils/locales'
@@ -144,6 +154,7 @@
144154
const props = defineProps<Props>()
145155
const { user } = toRefs(props)
146156
157+
const { appConfig } = useApp()
147158
const { dateFormat, timezone } = useAuthUser()
148159
149160
const userLanguage: ComputedRef<string> = computed(() =>
@@ -173,8 +184,12 @@
173184
text-transform: uppercase;
174185
border-bottom: 1px solid var(--card-border-color);
175186
}
176-
.raw-speed-help {
187+
.raw-speed-help,
188+
.missing-elevations-help {
177189
margin-top: -$default-margin * 0.5;
178190
}
191+
.missing-elevations-help {
192+
margin-bottom: $default-margin;
193+
}
179194
}
180195
</style>

fittrackee_client/src/components/User/ProfileEdition/UserPreferencesEdition.vue

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -256,7 +256,9 @@
256256
<select
257257
id="missing_elevations_processing"
258258
v-model="userForm.missing_elevations_processing"
259-
:disabled="authUserLoading"
259+
:disabled="
260+
!appConfig.elevation_services.open_elevation || authUserLoading
261+
"
260262
>
261263
<option
262264
v-for="item in missingElevationsProcessing"
@@ -267,6 +269,15 @@
267269
</option>
268270
</select>
269271
</label>
272+
<div
273+
v-if="!appConfig.elevation_services.open_elevation"
274+
class="info-box missing-elevations-help"
275+
>
276+
<span>
277+
<i class="fa fa-info-circle" aria-hidden="true" />
278+
{{ $t('user.PROFILE.NO_ELEVATION_SERVICE_AVAILABLE') }}
279+
</span>
280+
</div>
270281
<label class="form-items">
271282
{{ $t('visibility_levels.WORKOUTS_VISIBILITY') }}
272283
<select
@@ -395,7 +406,7 @@
395406
396407
const store = useStore()
397408
398-
const { errorMessages } = useApp()
409+
const { appConfig, errorMessages } = useApp()
399410
const { authUserLoading } = useAuthUser()
400411
401412
const weekStart = [
@@ -562,6 +573,7 @@
562573
userForm.segments_creation_event =
563574
user.segments_creation_event ?? 'only_manual'
564575
userForm.split_workout_charts = user.split_workout_charts
576+
userForm.missing_elevations_processing = user.missing_elevations_processing
565577
}
566578
function updateProfile() {
567579
store.dispatch(AUTH_USER_STORE.ACTIONS.UPDATE_USER_PREFERENCES, userForm)
@@ -638,5 +650,9 @@
638650
#missing_elevations_processing {
639651
padding: $default-padding * 0.5;
640652
}
653+
654+
.missing-elevations-help {
655+
margin-top: $default-margin * 0.5;
656+
}
641657
}
642658
</style>

0 commit comments

Comments
 (0)