Merge pull request #331 from jat255/add_elevation_chart_preference

Add elevation chart preference
This commit is contained in:
Sam 2023-04-08 11:12:00 +02:00 committed by GitHub
commit 337a882506
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
25 changed files with 111 additions and 15 deletions

View File

@ -55,6 +55,9 @@ docker-build-client:
docker-check-all: docker-bandit docker-lint-all docker-type-check docker-test-client docker-test-python
docker-downgrade-db:
docker-compose -f docker-compose-dev.yml exec fittrackee $(DOCKER_FLASK) db downgrade --directory $(DOCKER_MIGRATIONS)
docker-init: docker-run docker-init-db docker-restart docker-run-workers
docker-init-db:

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.01cb48d3.js"></script><script defer="defer" src="/static/js/app.9225ef92.js"></script><link href="/static/css/app.38b148d9.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.01cb48d3.js"></script><script defer="defer" src="/static/js/app.fbd9f0c5.js"></script><link href="/static/css/app.5f8309dc.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

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,35 @@
"""add user preference to start elevation plots at zero
Revision ID: db58d195c5bf
Revises: 374a670efe23
Create Date: 2023-03-14 04:14:23.781672
"""
from alembic import op
import sqlalchemy as sa
# revision identifiers, used by Alembic.
revision = 'db58d195c5bf'
down_revision = '374a670efe23'
branch_labels = None
depends_on = None
def upgrade():
# ### commands auto generated by Alembic - please adjust! ###
with op.batch_alter_table('users', schema=None) as batch_op:
batch_op.add_column(sa.Column('start_elevation_at_zero', sa.Boolean(), nullable=True))
op.execute("UPDATE users SET start_elevation_at_zero = true")
op.alter_column('users', 'start_elevation_at_zero', nullable=False)
# ### end Alembic commands ###
def downgrade():
# ### commands auto generated by Alembic - please adjust! ###
with op.batch_alter_table('users', schema=None) as batch_op:
batch_op.drop_column('start_elevation_at_zero')
# ### end Alembic commands ###

View File

@ -1482,6 +1482,7 @@ class TestUserPreferencesUpdate(ApiTestCaseMixin):
language=input_language,
imperial_units=True,
display_ascent=False,
start_elevation_at_zero=False,
date_format='yyyy-MM-dd',
)
),
@ -1493,6 +1494,7 @@ class TestUserPreferencesUpdate(ApiTestCaseMixin):
assert data['status'] == 'success'
assert data['message'] == 'user preferences updated'
assert data['data']['display_ascent'] is False
assert data['data']['start_elevation_at_zero'] is False
assert data['data']['imperial_units'] is True
assert data['data']['language'] == expected_language
assert data['data']['timezone'] == 'America/New_York'

View File

@ -869,6 +869,7 @@ def edit_user_preferences(auth_user: User) -> Union[Dict, HttpResponse]:
4,
6
],
"start_elevation_at_zero": true,
"timezone": "Europe/Paris",
"total_distance": 67.895,
"total_duration": "6:50:27",
@ -883,9 +884,9 @@ def edit_user_preferences(auth_user: User) -> Union[Dict, HttpResponse]:
:<json boolean display_ascent: display highest ascent records and total
:<json boolean imperial_units: display distance in imperial units
:<json string language: language preferences
:<json boolean start_elevation_at_zero: do elevation plots start at zero?
:<json string timezone: user time zone
:<json boolean weekm: does week start on Monday?
:<json boolean weekm: does week start on Monday?
:reqheader Authorization: OAuth 2.0 Bearer Token
@ -906,6 +907,7 @@ def edit_user_preferences(auth_user: User) -> Union[Dict, HttpResponse]:
'display_ascent',
'imperial_units',
'language',
'start_elevation_at_zero',
'timezone',
'weekm',
}
@ -916,6 +918,7 @@ def edit_user_preferences(auth_user: User) -> Union[Dict, HttpResponse]:
display_ascent = post_data.get('display_ascent')
imperial_units = post_data.get('imperial_units')
language = get_language(post_data.get('language'))
start_elevation_at_zero = post_data.get('start_elevation_at_zero')
timezone = post_data.get('timezone')
weekm = post_data.get('weekm')
@ -924,6 +927,7 @@ def edit_user_preferences(auth_user: User) -> Union[Dict, HttpResponse]:
auth_user.display_ascent = display_ascent
auth_user.imperial_units = imperial_units
auth_user.language = language
auth_user.start_elevation_at_zero = start_elevation_at_zero
auth_user.timezone = timezone
auth_user.weekm = weekm
db.session.commit()

View File

@ -59,6 +59,9 @@ class User(BaseModel):
confirmation_token = db.Column(db.String(255), nullable=True)
display_ascent = db.Column(db.Boolean, default=True, nullable=False)
accepted_policy_date = db.Column(db.DateTime, nullable=True)
start_elevation_at_zero = db.Column(
db.Boolean, default=True, nullable=False
)
def __repr__(self) -> str:
return f'<User {self.username!r}>'
@ -211,6 +214,7 @@ class User(BaseModel):
'display_ascent': self.display_ascent,
'imperial_units': self.imperial_units,
'language': self.language,
'start_elevation_at_zero': self.start_elevation_at_zero,
'timezone': self.timezone,
'weekm': self.weekm,
},

View File

@ -19,6 +19,8 @@
</dd>
<dt>{{ $t('user.PROFILE.ASCENT_DATA') }}:</dt>
<dd>{{ $t(`common.${display_ascent}`) }}</dd>
<dt>{{ $t('user.PROFILE.ELEVATION_CHART_START.LABEL') }}:</dt>
<dd>{{ $t(`user.PROFILE.ELEVATION_CHART_START.${user.start_elevation_at_zero ? 'ZERO' : 'MIN_ALT'}`) }}</dd>
</dl>
<div class="profile-buttons">
<button @click="$router.push('/profile/edit/preferences')">

View File

@ -99,6 +99,26 @@
</label>
</div>
</div>
<div class="form-items form-checkboxes">
<span class="checkboxes-label">
{{ $t('user.PROFILE.ELEVATION_CHART_START.LABEL') }}
</span>
<div class="checkboxes">
<label v-for="status in startElevationAtZeroData" :key="status.label">
<input
type="radio"
:id="status.label"
:name="status.label"
:checked="status.value === userForm.start_elevation_at_zero"
:disabled="loading"
@input="updateStartElevationAtZero(status.value)"
/>
<span class="checkbox-label">
{{ $t(`user.PROFILE.ELEVATION_CHART_START.${status.label}`) }}
</span>
</label>
</div>
</div>
<div class="form-buttons">
<button class="confirm" type="submit">
{{ $t('buttons.SUBMIT') }}
@ -170,6 +190,16 @@
value: false,
},
]
const startElevationAtZeroData = [
{
label: 'ZERO',
value: true
},
{
label: 'MIN_ALT',
value: false
}
]
const loading = computed(
() => store.getters[AUTH_USER_STORE.GETTERS.USER_LOADING]
)
@ -192,6 +222,7 @@
function updateUserForm(user: IAuthUserProfile) {
userForm.display_ascent = user.display_ascent
userForm.start_elevation_at_zero = user.start_elevation_at_zero ? user.start_elevation_at_zero : false
userForm.imperial_units = user.imperial_units ? user.imperial_units : false
userForm.language = user.language ? user.language : 'en'
userForm.timezone = user.timezone ? user.timezone : 'Europe/Paris'
@ -204,6 +235,9 @@
function updateTZ(value: string) {
userForm.timezone = value
}
function updateStartElevationAtZero(value: boolean) {
userForm.start_elevation_at_zero = value
}
function updateAscentDisplay(value: boolean) {
userForm.display_ascent = value
}

View File

@ -78,7 +78,7 @@
const { t } = useI18n()
const displayDistance = ref(true)
const beginElevationAtZero = ref(true)
const beginElevationAtZero = ref(props.authUser.start_elevation_at_zero)
const datasets: ComputedRef<IWorkoutChartData> = computed(() =>
getDatasets(props.workoutData.chartData, t, props.authUser.imperial_units)
)

View File

@ -69,6 +69,11 @@
"EDIT_PREFERENCES": "Edit preferences",
"EDIT_SPORTS_PREFERENCES": "Edit sports preferences",
"ERRORED_EMAIL_UPDATE": "Please {0} to change your email address again or contact the administrator",
"ELEVATION_CHART_START": {
"LABEL": "Elevation chart starts at",
"ZERO": "Zero",
"MIN_ALT": "Minimum altitude"
},
"FIRST_DAY_OF_WEEK": "First day of week",
"FIRST_NAME": "First name",
"LANGUAGE": "Language",

View File

@ -68,6 +68,11 @@
"EDIT": "Modifier le profil",
"EDIT_PREFERENCES": "Modifier les préférences",
"EDIT_SPORTS_PREFERENCES": "Modifier les préférences des sports",
"ELEVATION_CHART_START": {
"LABEL": "Début de l'axe pour le graphe affichant l'altitude",
"ZERO": "0",
"MIN_ALT": "Altitude minimale"
},
"ERRORED_EMAIL_UPDATE": "Veuillez vous {0} pour changer de nouveau votre adresse électronique ou contacter l'administrateur",
"FIRST_DAY_OF_WEEK": "Premier jour de la semaine",
"FIRST_NAME": "Prénom",

View File

@ -28,6 +28,7 @@ export interface IAuthUserProfile extends IUserProfile {
accepted_privacy_policy: boolean
display_ascent: boolean
imperial_units: boolean
start_elevation_at_zero: boolean
language: string | null
timezone: string
date_format: string
@ -63,6 +64,7 @@ export interface IAdminUserPayload {
export interface IUserPreferencesPayload {
display_ascent: boolean
start_elevation_at_zero: boolean
imperial_units: boolean
language: string
timezone: string