diff --git a/rowers/forms.py b/rowers/forms.py index deee532d..27bc35bc 100644 --- a/rowers/forms.py +++ b/rowers/forms.py @@ -1057,9 +1057,7 @@ class AnalysisOptionsForm(forms.Form): waterboattype = forms.MultipleChoiceField(choices=boattypes, label='Water Boat Type', initial = mytypes.waterboattype) - rankingonly = forms.BooleanField(initial=False, - label='Only Ranking Pieces', - required=False) + # form to select modality and boat type for trend flex @@ -1070,17 +1068,14 @@ class TrendFlexModalForm(forms.Form): waterboattype = forms.MultipleChoiceField(choices=boattypes, label='Water Boat Type', initial = mytypes.waterboattype) - rankingonly = forms.BooleanField(initial=False, - label='Only Ranking Pieces', - required=False) + # This form sets options for the summary stats page class StatsOptionsForm(forms.Form): includereststrokes = forms.BooleanField(initial=False,label='Include Rest Strokes',required=False) - rankingonly = forms.BooleanField(initial=False, - label='Only Ranking Pieces',required=False) + water = forms.BooleanField(initial=False,required=False) waterboattype = forms.MultipleChoiceField(choices=boattypes, label='Water Boat Type', @@ -1291,6 +1286,15 @@ class AnalysisChoiceForm(forms.Form): label='Include Rest Strokes') + def __init__(self, *args, **kwargs): + super(AnalysisChoiceForm, self).__init__(*args, **kwargs) + + if 'initial' in kwargs and kwargs['initial']['function'] == 'compare': + self.fields['xaxis'].initial = 'time' + self.fields['yaxis1'].initial = 'hr' + self.fields['plottype'].initial = 'line' + + class BoxPlotChoiceForm(forms.Form): yparam = forms.ChoiceField(choices=parchoices,initial='spm', diff --git a/rowers/mytypes.py b/rowers/mytypes.py index 8ba51758..fc249da2 100644 --- a/rowers/mytypes.py +++ b/rowers/mytypes.py @@ -41,6 +41,39 @@ workouttypes_ordered = collections.OrderedDict({ } ) +workouttypes_icons = collections.OrderedDict({ + 'water':'rowing.svg', # g + 'rower':'indoor_rower.svg', # g + 'skierg':'ski_erg.svg', #g + 'bikeerg':'bike_erg.svg', #g + 'dynamic':'indoor_rower.svg', + 'slides':'indoor_rower.svg', + 'paddle':'paddle.svg', # could be better + 'snow':'cross_country_ski.svg', # ok + 'coastal':'rowing.svg', # ok + 'c-boat':'rowing.svg', # ok + 'churchboat':'rowing.svg', # ok + 'Ride':'bike.svg', # ok + 'bike':'bike.svg', # ok + 'Run':'run.svg', # ok + 'NordicSki':'cross_country_ski.svg', # ok + 'Swim':'swim.svg', # ok + 'Hike':'hike.svg', # ok + 'Walk':'walk.svg', # o k + 'Canoeing':'canoeing.svg', # ok + 'Crossfit':'crossfit.svg', # ok + 'StandUpPaddling':'standup_paddling.svg', # ok + 'IceSkate':'ice_skating.svg', # ok + 'WeightTraining':'weight_training.svg', # ok + 'InlineSkate':'inline_skating.svg', + 'Kayaking':'kayaking.svg', # ok + 'Workout':'workout.svg', + 'Yoga':'yoga.svg', +# 'bike':'Bike', + 'other':'other.svg', + } +) + workouttypes = tuple((key, value) for key, value in workouttypes_ordered.items()) def Reverse(tuples): diff --git a/rowers/templates/bike.svg b/rowers/templates/bike.svg new file mode 100644 index 00000000..50a78948 --- /dev/null +++ b/rowers/templates/bike.svg @@ -0,0 +1,25 @@ + + + + + + diff --git a/rowers/templates/bike_erg.svg b/rowers/templates/bike_erg.svg new file mode 100644 index 00000000..05fd9ddd --- /dev/null +++ b/rowers/templates/bike_erg.svg @@ -0,0 +1,32 @@ + + + + + + + + + + + + diff --git a/rowers/templates/canoeing.svg b/rowers/templates/canoeing.svg new file mode 100644 index 00000000..6fd77453 --- /dev/null +++ b/rowers/templates/canoeing.svg @@ -0,0 +1,26 @@ + + + + + + + + + diff --git a/rowers/templates/coachrequestemail.html b/rowers/templates/coachrequestemail.html index 19965e7a..58e641b6 100644 --- a/rowers/templates/coachrequestemail.html +++ b/rowers/templates/coachrequestemail.html @@ -13,13 +13,14 @@ on behalf of {{ name }}.

- By accepting the invite, you are agreeing with the sharing + By accepting the invite, you are agreeing with the sharing of personal data according to our privacy policy.

To accept the login to the site and you will find the invitation here on the Teams page: - {{ siteurl }}/rowers/me/teams + {{ siteurl }}/rowers/me/teams, + including the email address of {{ name }}, if you need a contact.

You can also click the direct link: diff --git a/rowers/templates/cross_country_ski.svg b/rowers/templates/cross_country_ski.svg new file mode 100644 index 00000000..053971dc --- /dev/null +++ b/rowers/templates/cross_country_ski.svg @@ -0,0 +1,25 @@ + + + + + + + + + diff --git a/rowers/templates/crossfit.svg b/rowers/templates/crossfit.svg new file mode 100644 index 00000000..94424445 --- /dev/null +++ b/rowers/templates/crossfit.svg @@ -0,0 +1,27 @@ + + + + + + diff --git a/rowers/templates/gdpr_optin.html b/rowers/templates/gdpr_optin.html index 9e084f75..ae3d1a24 100644 --- a/rowers/templates/gdpr_optin.html +++ b/rowers/templates/gdpr_optin.html @@ -11,18 +11,24 @@ you can opt in or delete this user account.

-

GDPR Opt-In

+

Data Consent

To comply with the European Union General Data Protection Regulation, we need to record your consent to use personal data on this website. Please take some time to review our data policies. If you agree and opt in, click the "opt in" button at the bottom to be taken to the site. - If you do not agree, please use the red button to delete your + If you do not agree, please use the button at the end fo the page to delete your account. This will irreversibly delete all your data on rowsandall.com and remove your account.

+ +

+ OPT IN AND CONTINUE +

+ +
{% include "privacypolicy.html" %} @@ -33,26 +39,27 @@ To start or continue using the site, please give your consent by clicking on the green Opt In button below.

-

- Download your data -

+

- Opt in and continue + OPT IN AND CONTINUE

{% csrf_token %} - - + +

+

+ Download your data +

+ {% endblock %} {% block sidebar %} {% include 'menu_profile.html' %} {% endblock %} - diff --git a/rowers/templates/hike.svg b/rowers/templates/hike.svg new file mode 100644 index 00000000..23d9c5b5 --- /dev/null +++ b/rowers/templates/hike.svg @@ -0,0 +1,21 @@ + + + + + + + + + + diff --git a/rowers/templates/ice_skating.svg b/rowers/templates/ice_skating.svg new file mode 100644 index 00000000..d6381b02 --- /dev/null +++ b/rowers/templates/ice_skating.svg @@ -0,0 +1,23 @@ + + + + + + + + + diff --git a/rowers/templates/icons/bike.svg b/rowers/templates/icons/bike.svg new file mode 100644 index 00000000..53783f7f --- /dev/null +++ b/rowers/templates/icons/bike.svg @@ -0,0 +1,27 @@ + + + + + + + + diff --git a/rowers/templates/icons/bike_erg.svg b/rowers/templates/icons/bike_erg.svg new file mode 100644 index 00000000..b53b0f1f --- /dev/null +++ b/rowers/templates/icons/bike_erg.svg @@ -0,0 +1,32 @@ + + + + + + + + + + + + diff --git a/rowers/templates/icons/canoeing.svg b/rowers/templates/icons/canoeing.svg new file mode 100644 index 00000000..b749ff73 --- /dev/null +++ b/rowers/templates/icons/canoeing.svg @@ -0,0 +1,26 @@ + + + + + + + + + diff --git a/rowers/templates/icons/cross_country_ski.svg b/rowers/templates/icons/cross_country_ski.svg new file mode 100644 index 00000000..cf2207b7 --- /dev/null +++ b/rowers/templates/icons/cross_country_ski.svg @@ -0,0 +1,25 @@ + + + + + + + + + diff --git a/rowers/templates/icons/crossfit.svg b/rowers/templates/icons/crossfit.svg new file mode 100644 index 00000000..6f13a7b6 --- /dev/null +++ b/rowers/templates/icons/crossfit.svg @@ -0,0 +1,29 @@ + + + + + + + + diff --git a/rowers/templates/icons/hike.svg b/rowers/templates/icons/hike.svg new file mode 100644 index 00000000..89fa0a01 --- /dev/null +++ b/rowers/templates/icons/hike.svg @@ -0,0 +1,21 @@ + + + + + + + + + + diff --git a/rowers/templates/icons/ice_skating.svg b/rowers/templates/icons/ice_skating.svg new file mode 100644 index 00000000..50fa4775 --- /dev/null +++ b/rowers/templates/icons/ice_skating.svg @@ -0,0 +1,23 @@ + + + + + + + + + diff --git a/rowers/templates/icons/indoor_rower.svg b/rowers/templates/icons/indoor_rower.svg new file mode 100644 index 00000000..4eba251e --- /dev/null +++ b/rowers/templates/icons/indoor_rower.svg @@ -0,0 +1,24 @@ + + + + + + + + + diff --git a/rowers/templates/icons/inline_skating.svg b/rowers/templates/icons/inline_skating.svg new file mode 100644 index 00000000..1945100e --- /dev/null +++ b/rowers/templates/icons/inline_skating.svg @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + diff --git a/rowers/templates/icons/kayaking.svg b/rowers/templates/icons/kayaking.svg new file mode 100644 index 00000000..b4bad483 --- /dev/null +++ b/rowers/templates/icons/kayaking.svg @@ -0,0 +1,26 @@ + + + + + + + + + diff --git a/rowers/templates/icons/other.svg b/rowers/templates/icons/other.svg new file mode 100644 index 00000000..b3be09c4 --- /dev/null +++ b/rowers/templates/icons/other.svg @@ -0,0 +1,22 @@ + + + + + + + + diff --git a/rowers/templates/icons/paddle.svg b/rowers/templates/icons/paddle.svg new file mode 100644 index 00000000..2bba600a --- /dev/null +++ b/rowers/templates/icons/paddle.svg @@ -0,0 +1,25 @@ + + + + + + + + + + diff --git a/rowers/templates/icons/rowing.svg b/rowers/templates/icons/rowing.svg new file mode 100644 index 00000000..0644953d --- /dev/null +++ b/rowers/templates/icons/rowing.svg @@ -0,0 +1,23 @@ + + + + + + + + + diff --git a/rowers/templates/icons/run.svg b/rowers/templates/icons/run.svg new file mode 100644 index 00000000..3445f4fb --- /dev/null +++ b/rowers/templates/icons/run.svg @@ -0,0 +1,20 @@ + + + + + + + + diff --git a/rowers/templates/icons/ski_erg.svg b/rowers/templates/icons/ski_erg.svg new file mode 100644 index 00000000..2041a06b --- /dev/null +++ b/rowers/templates/icons/ski_erg.svg @@ -0,0 +1,29 @@ + + + + + + + + + + diff --git a/rowers/templates/icons/standup_paddling.svg b/rowers/templates/icons/standup_paddling.svg new file mode 100644 index 00000000..e60e9ace --- /dev/null +++ b/rowers/templates/icons/standup_paddling.svg @@ -0,0 +1,27 @@ + + + + + + + + + + diff --git a/rowers/templates/icons/swim.svg b/rowers/templates/icons/swim.svg new file mode 100644 index 00000000..08633397 --- /dev/null +++ b/rowers/templates/icons/swim.svg @@ -0,0 +1,20 @@ + + + + + + + + + + diff --git a/rowers/templates/icons/walk.svg b/rowers/templates/icons/walk.svg new file mode 100644 index 00000000..5f91dc00 --- /dev/null +++ b/rowers/templates/icons/walk.svg @@ -0,0 +1,18 @@ + + + + + + + + diff --git a/rowers/templates/icons/weight_training.svg b/rowers/templates/icons/weight_training.svg new file mode 100644 index 00000000..b3510111 --- /dev/null +++ b/rowers/templates/icons/weight_training.svg @@ -0,0 +1,28 @@ + + + + + + + + + + + + + diff --git a/rowers/templates/icons/workout.svg b/rowers/templates/icons/workout.svg new file mode 100644 index 00000000..f30fe27d --- /dev/null +++ b/rowers/templates/icons/workout.svg @@ -0,0 +1,17 @@ + + + + + + + + diff --git a/rowers/templates/icons/yoga.svg b/rowers/templates/icons/yoga.svg new file mode 100644 index 00000000..4a207e32 --- /dev/null +++ b/rowers/templates/icons/yoga.svg @@ -0,0 +1,19 @@ + + + + + + + + + diff --git a/rowers/templates/indoor_rower.svg b/rowers/templates/indoor_rower.svg new file mode 100644 index 00000000..998e3e05 --- /dev/null +++ b/rowers/templates/indoor_rower.svg @@ -0,0 +1,24 @@ + + + + + + + + + diff --git a/rowers/templates/inline_skating.svg b/rowers/templates/inline_skating.svg new file mode 100644 index 00000000..06fd9308 --- /dev/null +++ b/rowers/templates/inline_skating.svg @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + diff --git a/rowers/templates/kayaking.svg b/rowers/templates/kayaking.svg new file mode 100644 index 00000000..3027e2d7 --- /dev/null +++ b/rowers/templates/kayaking.svg @@ -0,0 +1,26 @@ + + + + + + + + + diff --git a/rowers/templates/list_workouts.html b/rowers/templates/list_workouts.html index d7fa0479..bb67af4b 100644 --- a/rowers/templates/list_workouts.html +++ b/rowers/templates/list_workouts.html @@ -12,32 +12,6 @@ type='text/javascript' src='https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js'> - {% endblock %} @@ -46,8 +20,11 @@ #mypointer { cursor: pointer; } + div.columns { width: 100%; } + div.columns div { width: 20%; padding: 10px; float: left; } + {% if team %}

{{ team.name }} Team Workouts

{% else %} @@ -97,16 +74,6 @@

- {% if rankingonly and not team %} - - Show All Workouts - - {% elif not team %} - - Show Only Ranking Pieces - - {% endif %} -

{% if workouts.has_previous %} @@ -153,143 +120,54 @@

-
  • {% if workouts %} - - - - - - - - - - - - - {% if not team %} - - {% else %} - - {% endif %} - - - {% for workout in workouts %} - {% if workout.rankingpiece %} - - {% else %} - - {% endif %} - - - - {% if workout|may_edit:request %} - {% if workout.name != '' %} - - {% else %} - - {% endif %} - {% else %} - {% if workout.name != '' %} - - {% else %} - - {% endif %} - {% endif %} - - - - - - {% if team %} - - {% endif %} - - - - - - - - + href={% url rower.defaultlandingpage id=workout.id|encode %} + title="Edit"> + + {% else %} +   + {% endif %} + + + {% endfor %} - -
    R Date Time Name Type Distance Duration Avg HR Max HR   - Owner -
    - {% if workout.rankingpiece %} - - {% else %} - - {% endif %} - {{ workout.date|date:"Y-m-d" }} {{ workout.starttime|date:"H:i" }} - +
  • + {{ workout.date|date:"Y-m-d" }} {{ workout.starttime|date:"H:i" }} +
  • - No Name - {{ workout.name }}No Name {{ workout.workouttype }} {{ workout.distance }}m {{ workout.duration |durationprint:"%H:%M:%S.%f" }} {{ workout.averagehr }} {{ workout.maxhr }} - {% if workout|may_edit:request %} - - {{ workout.user.user.first_name }} - {{ workout.user.user.last_name }} - - {% else %} - {{ workout.user.user.first_name }} - {{ workout.user.user.last_name }} - {% endif %} - - {% if workout|may_edit:request %} + + {% else %} +

    + No Name +

    + {% endif %} + +
    +
    + {% with workout.workouttype|icon|safe as templateName %} + {% include templateName %} + {% endwith %} +
    +
    + Distance
    + {{ workout.distance|distanceprint }} +
    +
    + Time
    + {{ workout.duration |durationprint:"%H:%M:%S.%f" }} +
    +
    + {% if workout|may_edit:request %} - - - {% else %} -   - {% endif %} -
    - - - - - - - - - - - - - - - - - {% if workout|may_edit:request %} - - - - {% else %} -   - {% endif %} -
    + {% else %} -

    No workouts found

    +
  • No workouts found
  • {% endif %} - {% if announcements %}
  • What's New?

    diff --git a/rowers/templates/menu_other.html b/rowers/templates/menu_other.html index 71789d84..f56facfa 100644 --- a/rowers/templates/menu_other.html +++ b/rowers/templates/menu_other.html @@ -10,9 +10,11 @@
  • {% if team %} -  Compare + +  Compare {% else %} -  Compare + +  Compare {% endif %}
  • diff --git a/rowers/templates/menu_workout.html b/rowers/templates/menu_workout.html index e161ca7a..16b38908 100644 --- a/rowers/templates/menu_workout.html +++ b/rowers/templates/menu_workout.html @@ -48,7 +48,7 @@
  • - +  Compare
  • diff --git a/rowers/templates/menu_workouts.html b/rowers/templates/menu_workouts.html index 4d0e2d02..24c0bc8f 100644 --- a/rowers/templates/menu_workouts.html +++ b/rowers/templates/menu_workouts.html @@ -10,10 +10,10 @@
  • {% if team %} - +  Compare {% else %} - +  Compare {% endif %}
  • diff --git a/rowers/templates/other.svg b/rowers/templates/other.svg new file mode 100644 index 00000000..184ebc08 --- /dev/null +++ b/rowers/templates/other.svg @@ -0,0 +1,20 @@ + + + + + + diff --git a/rowers/templates/paddle.svg b/rowers/templates/paddle.svg new file mode 100644 index 00000000..2ce5dc3a --- /dev/null +++ b/rowers/templates/paddle.svg @@ -0,0 +1,25 @@ + + + + + + + + + + diff --git a/rowers/templates/rowing.svg b/rowers/templates/rowing.svg new file mode 100644 index 00000000..478fbd8b --- /dev/null +++ b/rowers/templates/rowing.svg @@ -0,0 +1,23 @@ + + + + + + + + + diff --git a/rowers/templates/run.svg b/rowers/templates/run.svg new file mode 100644 index 00000000..7fa18a46 --- /dev/null +++ b/rowers/templates/run.svg @@ -0,0 +1,18 @@ + + + + + + diff --git a/rowers/templates/ski_erg.svg b/rowers/templates/ski_erg.svg new file mode 100644 index 00000000..e788f26b --- /dev/null +++ b/rowers/templates/ski_erg.svg @@ -0,0 +1,29 @@ + + + + + + + + + + diff --git a/rowers/templates/standup_paddling.svg b/rowers/templates/standup_paddling.svg new file mode 100644 index 00000000..b5d64b11 --- /dev/null +++ b/rowers/templates/standup_paddling.svg @@ -0,0 +1,27 @@ + + + + + + + + + + diff --git a/rowers/templates/svg/bike.svg b/rowers/templates/svg/bike.svg new file mode 100644 index 00000000..50a78948 --- /dev/null +++ b/rowers/templates/svg/bike.svg @@ -0,0 +1,25 @@ + + + + + + diff --git a/rowers/templates/svg/bike_erg.svg b/rowers/templates/svg/bike_erg.svg new file mode 100644 index 00000000..05fd9ddd --- /dev/null +++ b/rowers/templates/svg/bike_erg.svg @@ -0,0 +1,32 @@ + + + + + + + + + + + + diff --git a/rowers/templates/svg/canoeing.svg b/rowers/templates/svg/canoeing.svg new file mode 100644 index 00000000..6fd77453 --- /dev/null +++ b/rowers/templates/svg/canoeing.svg @@ -0,0 +1,26 @@ + + + + + + + + + diff --git a/rowers/templates/svg/cross_country_ski.svg b/rowers/templates/svg/cross_country_ski.svg new file mode 100644 index 00000000..053971dc --- /dev/null +++ b/rowers/templates/svg/cross_country_ski.svg @@ -0,0 +1,25 @@ + + + + + + + + + diff --git a/rowers/templates/svg/crossfit.svg b/rowers/templates/svg/crossfit.svg new file mode 100644 index 00000000..94424445 --- /dev/null +++ b/rowers/templates/svg/crossfit.svg @@ -0,0 +1,27 @@ + + + + + + diff --git a/rowers/templates/svg/hike.svg b/rowers/templates/svg/hike.svg new file mode 100644 index 00000000..23d9c5b5 --- /dev/null +++ b/rowers/templates/svg/hike.svg @@ -0,0 +1,21 @@ + + + + + + + + + + diff --git a/rowers/templates/svg/ice_skating.svg b/rowers/templates/svg/ice_skating.svg new file mode 100644 index 00000000..d6381b02 --- /dev/null +++ b/rowers/templates/svg/ice_skating.svg @@ -0,0 +1,23 @@ + + + + + + + + + diff --git a/rowers/templates/svg/indoor_rower.svg b/rowers/templates/svg/indoor_rower.svg new file mode 100644 index 00000000..998e3e05 --- /dev/null +++ b/rowers/templates/svg/indoor_rower.svg @@ -0,0 +1,24 @@ + + + + + + + + + diff --git a/rowers/templates/svg/inline_skating.svg b/rowers/templates/svg/inline_skating.svg new file mode 100644 index 00000000..06fd9308 --- /dev/null +++ b/rowers/templates/svg/inline_skating.svg @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + diff --git a/rowers/templates/svg/kayaking.svg b/rowers/templates/svg/kayaking.svg new file mode 100644 index 00000000..3027e2d7 --- /dev/null +++ b/rowers/templates/svg/kayaking.svg @@ -0,0 +1,26 @@ + + + + + + + + + diff --git a/rowers/templates/svg/other.svg b/rowers/templates/svg/other.svg new file mode 100644 index 00000000..184ebc08 --- /dev/null +++ b/rowers/templates/svg/other.svg @@ -0,0 +1,20 @@ + + + + + + diff --git a/rowers/templates/svg/paddle.svg b/rowers/templates/svg/paddle.svg new file mode 100644 index 00000000..2ce5dc3a --- /dev/null +++ b/rowers/templates/svg/paddle.svg @@ -0,0 +1,25 @@ + + + + + + + + + + diff --git a/rowers/templates/svg/rowing.svg b/rowers/templates/svg/rowing.svg new file mode 100644 index 00000000..478fbd8b --- /dev/null +++ b/rowers/templates/svg/rowing.svg @@ -0,0 +1,23 @@ + + + + + + + + + diff --git a/rowers/templates/svg/run.svg b/rowers/templates/svg/run.svg new file mode 100644 index 00000000..7fa18a46 --- /dev/null +++ b/rowers/templates/svg/run.svg @@ -0,0 +1,18 @@ + + + + + + diff --git a/rowers/templates/svg/ski_erg.svg b/rowers/templates/svg/ski_erg.svg new file mode 100644 index 00000000..e788f26b --- /dev/null +++ b/rowers/templates/svg/ski_erg.svg @@ -0,0 +1,29 @@ + + + + + + + + + + diff --git a/rowers/templates/svg/standup_paddling.svg b/rowers/templates/svg/standup_paddling.svg new file mode 100644 index 00000000..b5d64b11 --- /dev/null +++ b/rowers/templates/svg/standup_paddling.svg @@ -0,0 +1,27 @@ + + + + + + + + + + diff --git a/rowers/templates/svg/swim.svg b/rowers/templates/svg/swim.svg new file mode 100644 index 00000000..13b52084 --- /dev/null +++ b/rowers/templates/svg/swim.svg @@ -0,0 +1,22 @@ + + + + + + + + + + + + diff --git a/rowers/templates/svg/walk.svg b/rowers/templates/svg/walk.svg new file mode 100644 index 00000000..d51d7f33 --- /dev/null +++ b/rowers/templates/svg/walk.svg @@ -0,0 +1,16 @@ + + + + + + diff --git a/rowers/templates/svg/weight_training.svg b/rowers/templates/svg/weight_training.svg new file mode 100644 index 00000000..37ae236e --- /dev/null +++ b/rowers/templates/svg/weight_training.svg @@ -0,0 +1,28 @@ + + + + + + + + + + + + + diff --git a/rowers/templates/svg/workout.svg b/rowers/templates/svg/workout.svg new file mode 100644 index 00000000..427f2612 --- /dev/null +++ b/rowers/templates/svg/workout.svg @@ -0,0 +1,15 @@ + + + + + + diff --git a/rowers/templates/svg/yoga.svg b/rowers/templates/svg/yoga.svg new file mode 100644 index 00000000..11ba38da --- /dev/null +++ b/rowers/templates/svg/yoga.svg @@ -0,0 +1,19 @@ + + + + + + + + + diff --git a/rowers/templates/swim.svg b/rowers/templates/swim.svg new file mode 100644 index 00000000..13b52084 --- /dev/null +++ b/rowers/templates/swim.svg @@ -0,0 +1,22 @@ + + + + + + + + + + + + diff --git a/rowers/templates/team_compare_select.html b/rowers/templates/team_compare_select.html deleted file mode 100644 index 19140d18..00000000 --- a/rowers/templates/team_compare_select.html +++ /dev/null @@ -1,144 +0,0 @@ -{% extends "newbase.html" %} -{% load static %} -{% load rowerfilters %} - -{% block title %}Workouts{% endblock %} - -{% block main %} - - - - - -

    {{ team.name }} Compare Workouts

    - - - - -{% endblock %} - -{% block sidebar %} -{% include 'menu_workouts.html' %} -{% endblock %} diff --git a/rowers/templates/teambuttons.html b/rowers/templates/teambuttons.html index e45b807e..828d1769 100644 --- a/rowers/templates/teambuttons.html +++ b/rowers/templates/teambuttons.html @@ -6,7 +6,7 @@

    - Multi Compare + Multi Compare

    diff --git a/rowers/templates/teams.html b/rowers/templates/teams.html index 22e6ef47..be96301f 100644 --- a/rowers/templates/teams.html +++ b/rowers/templates/teams.html @@ -21,7 +21,7 @@ {{ team.name }} - Leave + Leave {% endfor %} @@ -29,7 +29,7 @@ {% endif %} - + {% if otherteams %}
  • Open Groups

    @@ -73,7 +73,7 @@ {{ team.name }} - Delete + Delete {% endfor %} @@ -98,7 +98,7 @@ {{ coach.user.first_name }} {{ coach.user.last_name }} - Remove @@ -124,7 +124,7 @@ {{ coachee.user.first_name }} {{ coachee.user.last_name }} - Remove @@ -138,11 +138,11 @@
  • Group Invitations and Requests

    This section lists open invites to join a group. By accepting - a group invite, you are agreeing with the sharing + a group invite, you are agreeing with the sharing of personal data between group members and coaches according to our privacy policy.

    - +

    As a group manager, by accepting a group invite, you are agreeing with our privacy policy regarding groups and personal data owned by group members.

    @@ -163,10 +163,10 @@ {{ i.team.name }} {{ i.team.manager.first_name }} {{ i.team.manager.last_name }} {{ user.first_name }} {{ user.last_name }} - Accept + Accept - Reject + Reject {% endfor %} @@ -184,9 +184,9 @@ {{ i.team.name }} {{ i.team.manager.first_name }} {{ i.team.manager.last_name }} {{ i.user.first_name }} {{ i.user.last_name }} - Accept + Accept - Reject + Reject {% endfor %} @@ -201,7 +201,7 @@ {% endif %}   - Revoke + Revoke {% endfor %} @@ -218,7 +218,7 @@ {{ form.as_table }}
    - + {% endif %} {% if mycoachrequests or mycoachoffers or coachoffers or coachrequests %} @@ -226,16 +226,17 @@

    Coaching Offers and Requests

    This section lists open offers and requests related to coaching. By accepting a coaching offer, the coach can run - analysis, add workouts and edit settings on behalf of the athlete. + analysis, add workouts and edit settings on behalf of the athlete. You agree to the sharing of personal data between athletes and coaches according to our privacy policy. -

    +

    + @@ -245,12 +246,13 @@ + {% endfor %} @@ -261,7 +263,7 @@ {% endfor %} @@ -272,7 +274,7 @@ @@ -282,12 +284,12 @@ @@ -312,14 +314,14 @@ {% endfor %}
    Coach UserE-mail Action  
    {{ i.coach.user.first_name }} {{ i.coach.user.last_name }} {{ i.user.first_name }} {{ i.user.last_name }}{{ i.user.email }} Accept - Reject + Reject
      - Revoke + Revoke
      Revoke
    {{ i.coach.user.first_name }} {{ i.coach.user.last_name }} {{ i.user.first_name }} {{ i.user.last_name }} Accept Reject
    {{ a.user.first_name }} {{ a.user.last_name }} Offer Coaching
    -
  • + {% endif %} {% if potentialcoaches %}
  • @@ -337,7 +339,7 @@ {{ c.first_name }} {{ c.last_name }} Request Coaching diff --git a/rowers/templates/walk.svg b/rowers/templates/walk.svg new file mode 100644 index 00000000..d51d7f33 --- /dev/null +++ b/rowers/templates/walk.svg @@ -0,0 +1,16 @@ + + + + + + diff --git a/rowers/templates/weight_training.svg b/rowers/templates/weight_training.svg new file mode 100644 index 00000000..37ae236e --- /dev/null +++ b/rowers/templates/weight_training.svg @@ -0,0 +1,28 @@ + + + + + + + + + + + + + diff --git a/rowers/templates/workout.svg b/rowers/templates/workout.svg new file mode 100644 index 00000000..427f2612 --- /dev/null +++ b/rowers/templates/workout.svg @@ -0,0 +1,15 @@ + + + + + + diff --git a/rowers/templates/yoga.svg b/rowers/templates/yoga.svg new file mode 100644 index 00000000..11ba38da --- /dev/null +++ b/rowers/templates/yoga.svg @@ -0,0 +1,19 @@ + + + + + + + + + diff --git a/rowers/templatetags/rowerfilters.py b/rowers/templatetags/rowerfilters.py index d51f18ac..57db8e3b 100644 --- a/rowers/templatetags/rowerfilters.py +++ b/rowers/templatetags/rowerfilters.py @@ -25,6 +25,7 @@ from rowers.c2stuff import c2_open from rowers.rower_rules import is_coach_user, is_workout_user, isplanmember,ispromember from rowers.mytypes import ( otwtypes,adaptivetypes,sexcategories,weightcategories,workouttypes, + workouttypes_icons, ) from rowers.utils import NoTokenError, step_to_string @@ -375,6 +376,14 @@ def ddays(ddelta): def spacetohtml(t): return t.replace(" ","%20") +@register.filter +def distanceprint(d): + if d<10000: + return "{d} m".format(d=d) + + d2 = d/1000. + return "%.2f km" % d2 + @register.filter def durationprint(d,dstring): if (d == None): # pragma: no cover @@ -480,6 +489,16 @@ def jsdict(dict,key): # pragma: no cover s = dict.get(key) return mark_safe(json.dumps(s)) +@register.filter +def icon(workouttype): + try: + s = workouttypes_icons.get(workouttype) + except KeyError: + s = "bike.svg" + + iconstring = "{s}".format(s=s) + + return iconstring @register.filter diff --git a/rowers/tests/statements.py b/rowers/tests/statements.py index 7d4f8187..74f2a1b8 100644 --- a/rowers/tests/statements.py +++ b/rowers/tests/statements.py @@ -36,7 +36,7 @@ from django.core.files.uploadedfile import SimpleUploadedFile from io import StringIO from django.test.client import RequestFactory -from rowers.views import c2_open, multi_compare_view +from rowers.views import c2_open from rowers.forms import ( diff --git a/rowers/tests/test_analysis.py b/rowers/tests/test_analysis.py index 819ab6a8..65c4e4f6 100644 --- a/rowers/tests/test_analysis.py +++ b/rowers/tests/test_analysis.py @@ -11,70 +11,6 @@ nu = datetime.datetime.now() from rowers.views import * from rowers.views.analysisviews import histodata -class WorkoutCompareTest(TestCase): - def setUp(self): - self.u = UserFactory() - - self.r = Rower.objects.create(user=self.u, - birthdate=faker.profile()['birthdate'], - gdproptin=True,surveydone=True, - gdproptindate=timezone.now(), - rowerplan='coach') - - self.c = Client() - self.user_workouts = WorkoutFactory.create_batch(5, user=self.r) - self.factory = RequestFactory() - self.password = faker.word() - self.u.set_password(self.password) - self.u.save() - - def tearDown(self): - for workout in self.user_workouts: - try: - os.remove(workout.csvfilename) - except (IOError, FileNotFoundError, OSError): - pass - - @patch('rowers.dataprep.create_engine') - @patch('rowers.dataprep.getsmallrowdata_db') - def test_workouts_compare(self, mocked_sqlalchemy, - mocked_getsmallrowdata_db): - - login = self.c.login(username=self.u.username, password=self.password) - self.assertTrue(login) - - url = '/rowers/team-compare-select/workout/'+encoded1+'/team/0/user/1/' - - response = self.c.get(url) - self.assertEqual(response.status_code,200) - - @patch('rowers.dataprep.create_engine') - @patch('rowers.dataprep.getsmallrowdata_db', side_effect=mocked_getsmallrowdata_db) - def test_workouts_compare_submit(self, mocked_sqlalchemy, - mocked_getsmallrowdata_db): - - login = self.c.login(username=self.u.username,password=self.password) - self.assertTrue(login) - - form_data = { - 'chartform':'Compare', - 'plottype':'scatter', - 'teamid':0, - 'workouts':['1','2','3'], - 'xparam':'distance', - 'yparam':'hr', - } - - form = WorkoutMultipleCompareForm(form_data) - chartform = ChartParamChoiceForm(form_data) - self.assertTrue(form.is_valid()) - self.assertTrue(chartform.is_valid()) - - response = self.c.post('/rowers/multi-compare/',form_data) - - self.assertEqual(response.status_code,200) - - class ListWorkoutTest(TestCase): @@ -298,7 +234,6 @@ class WorkoutCompareTestNew(TestCase): 'includereststrokes':False, 'modality':'all', 'waterboattype':['1x','2x','4x'], - 'rankingonly':False, 'workouts':[1,2,3] } @@ -396,7 +331,6 @@ class WorkoutBoxPlotTestNew(TestCase): 'includereststrokes':False, 'modality':'all', 'waterboattype':['1x','2x','4x'], - 'rankingonly':False, 'workouts':[1,2,3] } @@ -494,7 +428,6 @@ class WorkoutHistoTestNew(TestCase): 'includereststrokes':False, 'modality':'all', 'waterboattype':['1x','2x','4x'], - 'rankingonly':False, 'workouts':[1,2,3] } @@ -779,7 +712,6 @@ class WorkoutFlexallTestNew(TestCase): 'includereststrokes':False, 'modality':'all', 'waterboattype':['1x','2x','4x'], - 'rankingonly':False, 'workouts':[1,2,3] } @@ -884,7 +816,6 @@ class WorkoutStatsTestNew(TestCase): 'includereststrokes':False, 'modality':'all', 'waterboattype':['1x','2x','4x'], - 'rankingonly':False, 'ids':[1,2,3], 'userid':self.u.id, } @@ -947,7 +878,6 @@ class WorkoutStatsTestNew(TestCase): 'includereststrokes':False, 'modality':'all', 'waterboattype':['1x','2x','4x'], - 'rankingonly':False, 'ids':[1,2,3], 'userid':self.u.id, 'function':'boxplot' @@ -1019,7 +949,6 @@ class WorkoutStatsTestNew(TestCase): 'includereststrokes':False, 'modality':'all', 'waterboattype':['1x','2x','4x'], - 'rankingonly':False, 'workouts':[1,2,3] } diff --git a/rowers/tests/test_aworkouts.py b/rowers/tests/test_aworkouts.py index 5754eaaa..db8c24f1 100644 --- a/rowers/tests/test_aworkouts.py +++ b/rowers/tests/test_aworkouts.py @@ -14,7 +14,7 @@ from io import BytesIO from PIL import Image from io import StringIO - +from rowers.mytypes import workouttypes def create_image(storage, filename, size=(100, 100), image_mode='RGB', image_format='PNG'): """ @@ -31,6 +31,63 @@ def create_image(storage, filename, size=(100, 100), image_mode='RGB', image_for image_file = ContentFile(data.read()) return storage.save(filename, image_file) +class ListWorkoutTest(TestCase): + def setUp(self): + self.u = UserFactory() + + self.r = Rower.objects.create(user=self.u, + birthdate=faker.profile()['birthdate'], + gdproptin=True,surveydone=True, + gdproptindate=timezone.now(), + rowerplan='coach') + + self.c = Client() + self.user_workouts = WorkoutFactory.create_batch(len(workouttypes), user=self.r) + i = 0 + for workouttype in workouttypes: + self.user_workouts[i].workouttype = workouttype[0] + self.user_workouts[i].save() + i = i+1 + + self.factory = RequestFactory() + self.password = faker.word() + self.u.set_password(self.password) + self.u.save() + + def tearDown(self): + for workout in self.user_workouts: + try: + os.remove(workout.csvfilename) + except (IOError, FileNotFoundError,OSError): + pass + + @patch('rowers.dataprep.create_engine') + @patch('rowers.dataprep.getsmallrowdata_db') + @patch('rowers.dataprep.myqueue') + def test_list_workouts(self, mocked_sqlalchemy, + mocked_getsmallrowdata_db, + mocked_myqueue): + + login = self.c.login(username=self.u.username, password=self.password) + self.assertTrue(login) + + + + url = reverse('workouts_view') + + response = self.c.get(url) + self.assertEqual(response.status_code,200) + + url2 = url+'?page=2' + + response = self.c.get(url2) + self.assertEqual(response.status_code,200) + + url3 = url+'?page=3' + + response = self.c.get(url3) + self.assertEqual(response.status_code,200) + @override_settings(TESTING=True) class WorkoutViewTest(TestCase): def setUp(self): @@ -214,70 +271,6 @@ class WorkoutViewTest(TestCase): expected_url=expected_url, status_code=302,target_status_code=200) - @patch('rowers.dataprep.create_engine') - @patch('rowers.dataprep.getsmallrowdata_db') - @patch('rowers.middleware.myqueue') - def test_compares(self, mocked_sqlalchemy, mocked_getsmallrowdata_db, - mocked_myqueue): - login = self.c.login(username=self.u.username, password=self.password) - self.assertTrue(login) - - - session = self.c.session - session['ids'] = [self.werg1.id,self.werg2.id] - session.save() - - response = self.c.get('/') - - url = reverse('team_comparison_select') - response = self.c.get(url) - self.assertEqual(response.status_code,200) - - d1 = self.werg1.date-datetime.timedelta(days=2) - d2 = self.werg2.date+datetime.timedelta(days=2) - - form_data = { - 'startdate': d1.strftime('%Y-%m-%d'), - 'enddate': d2.strftime('%Y-%m-%d'), - 'modality':'water', - 'waterboattype':['1x'], - } - - form = DateRangeForm(form_data) - self.assertTrue(form.is_valid()) - - form = TrendFlexModalForm(form_data) - self.assertTrue(form.is_valid()) - - response = self.c.post(url,form_data) - self.assertEqual(response.status_code,200) - - url = reverse('multi_compare_view',kwargs={ - 'userid':self.u.id, - 'id':encoder.encode_hex(self.werg1.id), - }) - - form_data = { - 'xparam':'time', - 'yparam':'power', - 'plottype':'line', - 'teamid': '', - } - - - response = self.c.post(url,form_data,follow=True) - self.assertEqual(response.status_code,200) - - session['plottype'] = 'scatter' - session['xparam'] = 'time' - session['yparam'] = 'hr' - - session.save() - - response = self.c.get('/') - - response = self.c.get(url,follow=True) - self.assertEqual(response.status_code,200) @patch('rowers.dataprep.create_engine') @patch('rowers.dataprep.getsmallrowdata_db') diff --git a/rowers/tests/test_plans.py b/rowers/tests/test_plans.py index f6f5b73f..cc5de299 100644 --- a/rowers/tests/test_plans.py +++ b/rowers/tests/test_plans.py @@ -16,6 +16,7 @@ from django.db import transaction import json from rowers.views.workoutviews import plannedsession_compare_view +from rowers.views.analysisviews import analysis_new from rowers.views.otherviews import download_fit from rowers.opaque import encoder from django.utils.crypto import get_random_string @@ -443,7 +444,11 @@ class SessionLinkTest(TestCase): url = reverse(plannedsession_compare_view,kwargs={'id':ps.id,'userid':self.u.id}) response = self.c.get(url,follow=True) - expected_url = reverse('multi_compare_view',kwargs={'userid':self.u.id,'id':encoder.encode_hex(w.id)}) + expected_url = reverse('analysis_new', + kwargs={'function':'compare', + 'id':encoder.encode_hex(w.id), + 'session':ps.id, + }) self.assertRedirects(response,expected_url=expected_url, status_code=302,target_status_code=200) @@ -473,7 +478,7 @@ class SessionLinkTest(TestCase): session.save() request.user = self.u - response = multi_compare_view(request,id=str(w.id)) + response = analysis_new(request,id=encoder.encode_hex(w.id)) self.assertEqual(response.status_code,200) # and adding a get @@ -491,7 +496,7 @@ class SessionLinkTest(TestCase): session.save() request.user = self.u - response = multi_compare_view(request,id=str(w.id)) + response = analysis_new(request,id=encoder.encode_hex(w.id)) self.assertEqual(response.status_code,200) diff --git a/rowers/tests/test_team.py b/rowers/tests/test_team.py index ae4a0687..10c43b91 100644 --- a/rowers/tests/test_team.py +++ b/rowers/tests/test_team.py @@ -169,70 +169,6 @@ class TeamTest(TestCase): response = self.c.get(url) self.assertEqual(response.status_code, 200) - @patch('rowers.dataprep.create_engine') - @patch('rowers.dataprep.getsmallrowdata_db') - @patch('rowers.middleware.myqueue') - def test_compares(self, mocked_sqlalchemy, mocked_getsmallrowdata_db, - mocked_myqueue): - login = self.c.login(username=self.u.username, password=self.password) - self.assertTrue(login) - - - session = self.c.session - session['ids'] = [self.werg1.id,self.werg2.id] - session.save() - - response = self.c.get('/') - - url = reverse('team_comparison_select',kwargs={'teamid':self.t.id}) - response = self.c.get(url) - self.assertEqual(response.status_code,200) - - d1 = self.werg1.date-timedelta(days=2) - d2 = self.werg2.date+timedelta(days=2) - - form_data = { - 'startdate': d1.strftime('%Y-%m-%d'), - 'enddate': d2.strftime('%Y-%m-%d'), - 'modality':'water', - 'waterboattype':['1x'], - } - - form = DateRangeForm(form_data) - self.assertTrue(form.is_valid()) - - form = TrendFlexModalForm(form_data) - self.assertTrue(form.is_valid()) - - response = self.c.post(url,form_data) - self.assertEqual(response.status_code,200) - - url = reverse('multi_compare_view',kwargs={ - 'userid':self.u.id, - 'id':encoder.encode_hex(self.werg1.id), - }) - - form_data = { - 'xparam':'time', - 'yparam':'power', - 'plottype':'line', - 'teamid': '', - } - - - response = self.c.post(url,form_data,follow=True) - self.assertEqual(response.status_code,200) - - session['plottype'] = 'scatter' - session['xparam'] = 'time' - session['yparam'] = 'hr' - - session.save() - - response = self.c.get('/') - - response = self.c.get(url,follow=True) - self.assertEqual(response.status_code,200) def test_teamsview(self): diff --git a/rowers/tests/test_urls.py b/rowers/tests/test_urls.py index c34057d8..b8986110 100644 --- a/rowers/tests/test_urls.py +++ b/rowers/tests/test_urls.py @@ -93,7 +93,6 @@ class URLTests(TestCase): '/rowers/list-graphs/', '/rowers/list-jobs/', '/rowers/list-workouts/', - '/rowers/list-workouts/ranking/', '/rowers/list-workouts/user/1/', '/rowers/me/calcdps/', '/rowers/me/edit/', @@ -125,8 +124,6 @@ class URLTests(TestCase): '/rowers/sessions/multicreate/', '/rowers/sessions/print/', '/rowers/sessions/teamcreate/', - '/rowers/team-compare-select/', - '/rowers/team-compare-select/workout/'+encoded1+'/', '/rowers/workout/'+encoded1+'/', '/rowers/workout/'+encoded1+'/adddistanceplot/', '/rowers/workout/'+encoded1+'/adddistanceplot2/', @@ -157,7 +154,6 @@ class URLTests(TestCase): '/rowers/workout/'+encoded1+'/split/', '/rowers/workout/'+encoded1+'/stats/', '/rowers/workout/'+encoded1+'/stream/', - '/rowers/workout/'+encoded1+'/toggle-ranking/', '/rowers/workout/'+encoded1+'/undosmoothenpace/', '/rowers/workout/'+encoded1+'/unsubscribe/', '/rowers/workout/'+encoded1+'/view/', diff --git a/rowers/tests/viewnames.csv b/rowers/tests/viewnames.csv index a9b88233..34c2b7cd 100644 --- a/rowers/tests/viewnames.csv +++ b/rowers/tests/viewnames.csv @@ -23,7 +23,6 @@ 22,24,courses_view,see race courses,TRUE,200,FALSE,200,302,FALSE,200,302,FALSE,200,302,FALSE,FALSE,FALSE,TRUE,TRUE, 23,25,course_upload_view,upload a new course,TRUE,302,basic,200,302,FALSE,200,302,FALSE,200,302,FALSE,FALSE,FALSE,TRUE,TRUE, 24,26,addmanual_view,upload a manual workout,TRUE,302,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,TRUE,TRUE, -25,27,team_comparison_select,compare with a team member workout,TRUE,302,pro,200,302,pro,200,302,coach,200,302,FALSE,TRUE,TRUE,TRUE,TRUE, 26,28,workouts_join_view,join workouts,TRUE,302,pro,302,302,pro,403,403,coach,302,403,FALSE,TRUE,FALSE,TRUE,TRUE, 27,29,workouts_join_select,select workouts to join,TRUE,404,pro,200,302,pro,403,403,coach,200,403,FALSE,TRUE,FALSE,TRUE,TRUE, 29,31,analysis_new,analysis front page,TRUE,302,pro,200,302,FALSE,200,302,coach,200,302,FALSE,TRUE,FALSE,TRUE,TRUE, @@ -97,7 +96,6 @@ 111,137,workout_recalcsummary_view,recalculates workout summary,TRUE,403,basic,302,403,basic,403,403,coach,302,403,FALSE,FALSE,TRUE,TRUE,TRUE, 112,138,workout_sporttracks_upload_view,uploads workout to C2,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,TRUE,FALSE,FALSE, 115,141,workout_tp_upload_view,uploads workout to C2,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,TRUE,FALSE,FALSE, -116,142,multi_compare_view,compare workouts ,TRUE,302,basic,302,403,basic,302,403,coach,302,302,FALSE,FALSE,TRUE,TRUE,TRUE, 117,145,alerts_view,view alerts,TRUE,302,basic,200,403,basic,403,403,coach,200,302,FALSE,TRUE,FALSE,TRUE,TRUE, 118,147,AlertDelete,delete alert,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE, 119,148,alert_edit_view,edit alert,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE, diff --git a/rowers/urls.py b/rowers/urls.py index 25bbf732..71254ad5 100644 --- a/rowers/urls.py +++ b/rowers/urls.py @@ -261,14 +261,10 @@ urlpatterns = [ views.agegrouprecordview,name='agegrouprecordview'), re_path(r'^agegrouprecords/$', views.agegrouprecordview,name='agegrouprecordview'), - re_path(r'^list-workouts/ranking/$',views.workouts_view,{'rankingonly':True}, - name='workouts_view'), re_path(r'^list-workouts/team/(?P\d+)/$',views.workouts_view, name='workouts_view'), re_path(r'^(?P\d+)/list-workouts/$',views.workouts_view, name='workouts_view'), - re_path(r'^list-workouts/ranking/user/(?P\d+)/$',views.workouts_view,{'rankingonly':True}, - name='workouts_view'), re_path(r'^list-workouts/user/(?P\d+)/$',views.workouts_view, name='workouts_view'), re_path(r'^virtualevents/$',views.virtualevents_view,name='virtualevents_view'), @@ -312,24 +308,16 @@ urlpatterns = [ re_path(r'^standards/upload/(?P\d+)/$',views.standards_upload_view,name='standards_upload_view'), re_path(r'^workout/addmanual/(?P\d+)/$',views.addmanual_view,name='addmanual_view'), re_path(r'^workout/addmanual/$',views.addmanual_view,name='addmanual_view'), - re_path(r'^team-compare-select/workout/(?P\d+)/team/(?P\d+)/user/(?P\d+)/$',views.team_comparison_select,name='team_comparison_select'), - re_path(r'^team-compare-select/workout/(?P\b[0-9A-Fa-f]+\b)/team/(?P\d+)/$',views.team_comparison_select,name='team_comparison_select'), - re_path(r'^team-compare-select/workout/(?P\b[0-9A-Fa-f]+\b)/team/(?P\d+)/$',views.team_comparison_select,name='team_comparison_select'), - re_path(r'^team-compare-select/workout/(?P\b[0-9A-Fa-f]+\b)/team/(?P\d+)/user/(?P\d+)/$',views.team_comparison_select,name='team_comparison_select'), - re_path(r'^team-compare-select/(?P\d+-\d+-\d+)/(?P\d+-\d+-\d+)/$',views.team_comparison_select,name='team_comparison_select'), - re_path(r'^team-compare-select/workout/(?P\b[0-9A-Fa-f]+\b)/user/(?P\d+)/$',views.team_comparison_select,name='team_comparison_select'), - re_path(r'^team-compare-select/team/(?P\d+)/user/(?P\d+)/$',views.team_comparison_select,name='team_comparison_select'), - re_path(r'^team-compare-select/workout/(?P\b[0-9A-Fa-f]+\b)/$',views.team_comparison_select,name='team_comparison_select'), - re_path(r'^team-compare-select/team/(?P\d+)/$',views.team_comparison_select,name='team_comparison_select'), - re_path(r'^team-compare-select/user/(?P\d+)/$',views.team_comparison_select,name='team_comparison_select'), - re_path(r'^team-compare-select/$',views.team_comparison_select,name='team_comparison_select'), re_path(r'^workouts-join/$',views.workouts_join_view,name='workouts_join_view'), re_path(r'^workouts-join/user/(?P\d+)$',views.workouts_join_view,name='workouts_join_view'), re_path(r'^workouts-join-select/$',views.workouts_join_select,name='workouts_join_select'), re_path(r'^workouts-join-select/user/(?P\d+)/$',views.workouts_join_select,name='workouts_join_select'), + re_path(r'^user-analysis-select/(?P\w.*)/team/(?P\d+)/workout/(?P\b[0-9A-Fa-f]+\b)/$',views.analysis_new,name='analysis_new'), + re_path(r'^user-analysis-select/(?P\w.*)/session/(?P\d+)/workout/(?P\b[0-9A-Fa-f]+\b)/$',views.analysis_new,name='analysis_new'), re_path(r'^user-analysis-select/(?P\w.*)/workout/(?P\b[0-9A-Fa-f]+\b)/$',views.analysis_new,name='analysis_new'), re_path(r'^user-analysis-select/(?P\w.*)/user/(?P\d+)/$',views.analysis_new,name='analysis_new'), re_path(r'^user-analysis-select/(?P\w.*)/team/(?P\d+)/$',views.analysis_new,name='analysis_new'), + re_path(r'^user-analysis-select/team/(?P\d+)/workout/(?P\b[0-9A-Fa-f]+\b)/$',views.analysis_new,name='analysis_new'), re_path(r'^user-analysis-select/user/(?P\d+)/$',views.analysis_new,name='analysis_new'), re_path(r'^user-analysis-select/team/(?P\d+)/$',views.analysis_new,name='analysis_new'), re_path(r'^user-analysis-select/(?P\w.*)/$',views.analysis_new,name='analysis_new'), @@ -522,10 +510,6 @@ urlpatterns = [ re_path(r'^workout/(?P\b[0-9A-Fa-f]+\b)/recalcsummary/$',views.workout_recalcsummary_view,name='workout_recalcsummary_view'), re_path(r'^workout/(?P\b[0-9A-Fa-f]+\b)/sporttracksuploadw/$',views.workout_sporttracks_upload_view,name='workout_sporttracks_upload_view'), re_path(r'^workout/(?P\b[0-9A-Fa-f]+\b)/tpuploadw/$',views.workout_tp_upload_view,name='workout_tp_upload_view'), - re_path(r'^multi-compare/workout/(?P\b[0-9A-Fa-f]+\b)/user/(?P\d+)/$',views.multi_compare_view, - name='multi_compare_view'), - re_path(r'^multi-compare/workout/(?P\b[0-9A-Fa-f]+\b)/$',views.multi_compare_view,name='multi_compare_view'), - re_path(r'^multi-compare/$',views.multi_compare_view,name='multi_compare_view'), re_path(r'^alerts/user/(?P\d+)/$',views.alerts_view,name='alerts_view'), re_path(r'^alerts/$',views.alerts_view,name='alerts_view'), re_path(r'^alerts/(?P\d+)/delete/$',views.AlertDelete.as_view(),name='alert_delete_view'), diff --git a/rowers/utils.py b/rowers/utils.py index b6feb80a..596fc4ff 100644 --- a/rowers/utils.py +++ b/rowers/utils.py @@ -36,11 +36,14 @@ import arrow lbstoN = 4.44822 landingpages = ( + ('workout_view', 'Workout View'), ('workout_edit_view','Edit View'), ('workout_workflow_view','Workflow View'), ('workout_stats_view','Stats View'), ('workout_data_view','Data Explore View'), ('workout_summary_edit_view','Intervals Editor'), + ('workout_flexchart_stacked_view','Workout Stacked Chart'), + ('workout_flexchart3_view','Workout Flex Chart') ) diff --git a/rowers/views/analysisviews.py b/rowers/views/analysisviews.py index 9f62d9bf..6b1b234a 100644 --- a/rowers/views/analysisviews.py +++ b/rowers/views/analysisviews.py @@ -8,6 +8,7 @@ from rowers.views.statements import * import collections import simplejson from jinja2 import Template,Environment,FileSystemLoader +from rowers.rower_rules import can_view_session def floatformat(x,prec=2): # pragma: no cover return '{x}'.format(x=round(x,prec)) @@ -26,7 +27,6 @@ defaultoptions = { 'includereststrokes': False, 'workouttypes':['rower','dynamic','slides'], 'waterboattype': mytypes.waterboattype, - 'rankingonly': False, 'function':'boxplot' } @@ -35,7 +35,7 @@ defaultoptions = { message="This functionality requires a Pro plan or higher. If you are already a Pro user, please log in to access this functionality", redirect_field_name=None) @permission_required('rower.is_coach',fn=get_user_by_userid,raise_exception=True) -def analysis_new(request,userid=0,function='boxplot',teamid=0,id=''): +def analysis_new(request,userid=0,function='boxplot',teamid=0,id='',session=0): r = getrequestrower(request, userid=userid) user = r.user userid = user.id @@ -53,6 +53,13 @@ def analysis_new(request,userid=0,function='boxplot',teamid=0,id=''): except Team.DoesNotExist: theteam = None + try: + thesession = PlannedSession.objects.get(id=session) + if not can_view_session(user,thesession): + raise PermissionDenied("you cannot view this session") + except PlannedSession.DoesNotExist: + thesession = None + if 'options' in request.session: options = request.session['options'] @@ -78,11 +85,6 @@ def analysis_new(request,userid=0,function='boxplot',teamid=0,id=''): worldclass = False - try: - rankingonly = options['rankingonly'] - except KeyError: # pragma: no cover - rankingonly = False - try: includereststrokes = options['includereststrokes'] except KeyError: # pragma: no cover @@ -129,12 +131,6 @@ def analysis_new(request,userid=0,function='boxplot',teamid=0,id=''): if modality != 'water': waterboattype = [b[0] for b in mytypes.boattypes] - - if 'rankingonly' in optionsform.cleaned_data: - rankingonly = optionsform.cleaned_data['rankingonly'] - else: # pragma: no cover - rankingonly = False - options['modalities'] = modalities options['waterboattype'] = waterboattype try: @@ -211,6 +207,8 @@ def analysis_new(request,userid=0,function='boxplot',teamid=0,id=''): startdatetime__lte=enddate, workouttype__in=modalities, ) + elif thesession is not None: + workouts = get_workouts_session(r,thesession) else: workouts = Workout.objects.filter(user=r, startdatetime__gte=startdate, @@ -224,8 +222,6 @@ def analysis_new(request,userid=0,function='boxplot',teamid=0,id=''): ).exclude(boattype__in=negtypes) - if rankingonly: # pragma: no cover - workouts = workouts.exclude(rankingpiece=False) query = request.POST.get('q') if query: # pragma: no cover @@ -257,7 +253,6 @@ def analysis_new(request,userid=0,function='boxplot',teamid=0,id=''): optionsform = AnalysisOptionsForm(initial={ 'modality':modality, 'waterboattype':waterboattype, - 'rankingonly':rankingonly, }) diff --git a/rowers/views/paymentviews.py b/rowers/views/paymentviews.py index 11a8c22d..268240cb 100644 --- a/rowers/views/paymentviews.py +++ b/rowers/views/paymentviews.py @@ -784,10 +784,11 @@ def useractivate(request, uidb64, token): # pragma: no cover ['roosendaalsander@gmail.com']) - messages.info(request,'Thank you for your email confirmation. Now you can login to your account.') - url = '/login/' - if user.rower.rowerplan == 'freecoach': - url+='?next=/rowers/me/teams' + messages.info(request,'Thank you for your email confirmation. YOu are now signed in to your account.') + login(request, user, backend=settings.AUTHENTICATION_BACKENDS[0]) + url = reverse('workouts_view') + #if user.rower.rowerplan == 'freecoach': + # url+='?next=/rowers/me/teams' return HttpResponseRedirect(url) else: return render(request, diff --git a/rowers/views/workoutviews.py b/rowers/views/workoutviews.py index 00b1e4a5..95a477e9 100644 --- a/rowers/views/workoutviews.py +++ b/rowers/views/workoutviews.py @@ -867,7 +867,6 @@ defaultoptions = { 'includereststrokes': False, 'workouttypes':['rower','dynamic','slides'], 'waterboattype': mytypes.waterboattype, - 'rankingonly': False, 'function':'boxplot' } @@ -901,12 +900,6 @@ def video_selectworkout(request,userid=0): modality = 'all' - - try: - rankingonly = options['rankingonly'] - except KeyError: # pragma: no cover - rankingonly = False - query = request.GET.get('q') if query: # pragma: no cover query_list = query.split() @@ -1002,9 +995,6 @@ def video_selectworkout(request,userid=0): ).exclude(boattype__in=negtypes) - if rankingonly: # pragma: no cover - workouts = workouts.exclude(rankingpiece=False) - startdatestring = startdate.strftime('%Y-%m-%d') enddatestring = enddate.strftime('%Y-%m-%d') request.session['startdate'] = startdatestring @@ -1254,227 +1244,7 @@ def remove_power_view(request,id=0): @user_passes_test(ispromember,login_url='/rowers/paidplans/', message="This functionality requires a Pro plan or higher. If you are already a Pro user, please log in to access this functionality. If you are already a Pro user, please log in to access this functionality", redirect_field_name=None) -def team_comparison_select(request, - startdatestring="", - enddatestring="", - message='', - successmessage='', - userid=0, - startdate=timezone.now()-datetime.timedelta(days=30), - enddate=timezone.now(), - id=0, - teamid=0): - r = getrequestrower(request,userid=userid) - requestrower = getrower(request.user) - - - request.session.pop('ps',None) - - if 'waterboattype' in request.session: - waterboattype = request.session['waterboattype'] - else: - waterboattype = mytypes.waterboattype - - if 'rankingonly' in request.session: # pragma: no cover - rankingonly = request.session['rankingonly'] - else: - rankingonly = False - - if 'modalities' in request.session: - modalities = request.session['modalities'] - if len(modalities) > 1: # pragma: no cover - modality = 'all' - else: - modality = modalities[0] - else: - modalities = [m[0] for m in mytypes.workouttypes] - modality = 'all' - - if request.method == 'POST': - dateform = DateRangeForm(request.POST) - if dateform.is_valid(): - startdate = dateform.cleaned_data['startdate'] - enddate = dateform.cleaned_data['enddate'] - startdatestring = startdate.strftime('%Y-%m-%d') - enddatestring = enddate.strftime('%Y-%m-%d') - request.session['startdate'] = startdatestring - request.session['enddate'] = enddatestring - - modalityform = TrendFlexModalForm(request.POST) - if modalityform.is_valid(): - modality = modalityform.cleaned_data['modality'] - waterboattype = modalityform.cleaned_data['waterboattype'] - if modality == 'all': # pragma: no cover - modalities = [m[0] for m in mytypes.workouttypes] - else: - modalities = [modality] - - if modality != 'water': # pragma: no cover - waterboattype = [b[0] for b in mytypes.boattypes] - - - if 'rankingonly' in modalityform.cleaned_data: - rankingonly = modalityform.cleaned_data['rankingonly'] - else: # pragma: no cover - rankingonly = False - - request.session['modalities'] = modalities - request.session['waterboattype'] = waterboattype - else: - dateform = DateRangeForm(initial={ - 'startdate':startdate, - 'enddate':enddate, - }) - modalityform = TrendFlexModalForm(initial={ - 'modality':modality, - 'waterboattype':waterboattype, - 'rankingonly':rankingonly, - }) - - - - - negtypes = [] - for b in mytypes.boattypes: - if b[0] not in waterboattype: - negtypes.append(b[0]) - - startdate = datetime.datetime.combine(startdate,datetime.time()) - enddate = datetime.datetime.combine(enddate,datetime.time(23,59,59)) - #enddate = enddate+datetime.timedelta(days=1) - - if startdatestring: - startdate = iso8601.parse_date(startdatestring) - if enddatestring: - enddate = iso8601.parse_date(enddatestring) - - if enddate < startdate: # pragma: no cover - s = enddate - enddate = startdate - startdate = s - - try: - theteam = Team.objects.get(id=teamid) - except Team.DoesNotExist: - theteam = 0 - - # make sure the dates are not naive - try: - startdate = pytz.utc.localize(startdate) - except ValueError: - pass - try: - enddate = pytz.utc.localize(enddate) - except ValueError: - pass - - if theteam and (theteam.viewing == 'allmembers' or theteam.manager == request.user): - workouts = Workout.objects.filter(team=theteam, - startdatetime__gte=startdate, - startdatetime__lte=enddate, - workouttype__in=modalities).order_by("-date", "-starttime").exclude(boattype__in=negtypes) - elif theteam and theteam.viewing == 'coachonly': # pragma: no cover - workouts = Workout.objects.filter(team=theteam,user=r, - startdatetime__gte=startdate, - startdatetime__lte=enddate, - workouttype__in=modalities).order_by("-date","-starttime").exclude(boattype__in=negtypes) - - - else: - theteam = None - workouts = Workout.objects.filter(user=r, - startdatetime__gte=startdate, - startdatetime__lte=enddate, - workouttype__in=modalities).order_by("-date", "-starttime").exclude(boattype__in=negtypes) - - if rankingonly: # pragma: no cover - workouts = workouts.exclude(rankingpiece=False) - - query = request.GET.get('q') - if query: # pragma: no cover - query_list = query.split() - workouts = workouts.filter( - reduce(operator.and_, - (Q(name__icontains=q) for q in query_list)) | - reduce(operator.and_, - (Q(notes__icontains=q) for q in query_list)) - ) - searchform = SearchForm(initial={'q':query}) - else: - searchform = SearchForm() - - if id: - firstworkout = get_workout(id) - if not is_workout_team(request.user,firstworkout): # pragma: no cover - raise PermissionDenied("You are not allowed to use this workout") - - firstworkoutquery = Workout.objects.filter(id=encoder.decode_hex(id)) - workouts = firstworkoutquery | workouts - else: - firstworkout = None - - form = WorkoutMultipleCompareForm() - form.fields["workouts"].queryset = workouts - if id: - form.fields["workouts"].initial = [firstworkout] - - - - if theteam: - theid = theteam.id - else: - theid = 0 - - chartform = ChartParamChoiceForm(initial={'teamid':0}) - - messages.info(request,successmessage) - messages.error(request,message) - - if id: - breadcrumbs = [ - { - 'url':'/rowers/list-workouts/', - 'name':'Workouts' - }, - { - 'url':get_workout_default_page(request,id), - 'name': firstworkout.name - }, - { - 'url':reverse('team_comparison_select',kwargs={'id':id,'teamid':teamid}), - 'name':'Compare Select' - }, - ] - else: - breadcrumbs = [ - { - 'url':'/rowers/list-workouts/', - 'name':'Workouts' - }, - { - 'url':reverse('team_comparison_select',kwargs={'teamid':teamid}), - 'name': 'Compare Select' - }, - - ] - - return render(request, 'team_compare_select.html', - {'workouts': workouts, - 'workout':firstworkout, - 'dateform':dateform, - 'startdate':startdate, - 'enddate':enddate, - 'team':theteam, - 'searchform':searchform, - 'form':form, - 'rower':r, - 'breadcrumbs':breadcrumbs, - 'active':'nav-workouts', - 'chartform':chartform, - 'modalityform':modalityform, - 'teams':get_my_teams(request.user), - }) def course_mapcompare_view(request,id=0): results = [] @@ -2047,168 +1817,24 @@ def plannedsession_compare_view(request,id=0,userid=0): request.session['plottype'] = plottype request.session['ps'] = ps.id + teams = ps.team.all() + if ids: - url = reverse('multi_compare_view', - kwargs={'userid':userid,'id':encoder.encode_hex(ids[0])}) + url = reverse('analysis_new', + kwargs={ + 'session':ps.id, + 'id':encoder.encode_hex(ids[0]), + 'function':'compare'}) else: url = reverse('plannedsession_view',kwargs={'id':ps.id}) return HttpResponseRedirect(url) -# Team comparison -@login_required() -def multi_compare_view(request,id=0,userid=0): - promember=0 - if not request.user.is_anonymous: - r = getrower(request.user) - result = request.user.is_authenticated and ispromember(request.user) - if result: - promember=1 - - if request.method == 'POST' and 'workouts' in request.POST: - form = WorkoutMultipleCompareForm(request.POST) - chartform = ChartParamChoiceForm(request.POST) - if form.is_valid() and chartform.is_valid(): - cd = form.cleaned_data - workouts = cd['workouts'] - xparam = chartform.cleaned_data['xparam'] - yparam = chartform.cleaned_data['yparam'] - plottype = chartform.cleaned_data['plottype'] - teamid = chartform.cleaned_data['teamid'] - ids = [int(w.id) for w in workouts] - request.session['ids'] = ids - - labeldict = { - int(w.id): w.__str__() for w in workouts - } - - else: # pragma: no cover - return HttpResponse("Form is not valid") - elif request.method == 'POST' and 'ids' in request.session: - chartform = ChartParamChoiceForm(request.POST) - if chartform.is_valid(): - xparam = chartform.cleaned_data['xparam'] - yparam = chartform.cleaned_data['yparam'] - plottype = chartform.cleaned_data['plottype'] - teamid = chartform.cleaned_data['teamid'] - ids = request.session['ids'] - request.session['ids'] = ids - workouts = [] - for id in ids: - try: - workouts.append(Workout.objects.get(id=id)) - except Workout.DoesNotExist: # pragma: no cover - pass - - labeldict = { - int(w.id): w.__str__() for w in workouts - } - elif 'ids' in request.session and 'plottype' in request.session: - xparam = request.session['xparam'] - yparam = request.session['yparam'] - plottype = request.session['plottype'] - teamid = 0 - ids = request.session['ids'] - workouts = [] - for id in ids: - try: - workouts.append(Workout.objects.get(id=id)) - except Workout.DoesNotExist: # pragma: no cover - pass - - labeldict = { - int(w.id): w.__str__() for w in workouts - } - chartform = ChartParamChoiceForm( - initial = { - 'xparam':xparam, - 'yparam':yparam, - 'plottype':plottype, - 'teamid':teamid - } - ) - - else: - url = reverse('team_comparison_select', - kwargs={ - 'id':id, - 'teamid':0}) - return HttpResponseRedirect(url) - - - res = interactive_multiple_compare_chart(ids,xparam,yparam, - promember=promember, - plottype=plottype, - labeldict=labeldict) - script = res[0] - div = res[1] - errormessage = res[3] - if errormessage != '': # pragma: no cover - messages.error(request,errormessage) - - r = getrower(request.user) - - breadcrumbs = [ - { - 'url':'/rowers/list-workouts/', - 'name':'Workouts' - }, - { - 'url':reverse('team_comparison_select',kwargs={'teamid':teamid}), - 'name': 'Compare Select' - }, - { - 'url':reverse('multi_compare_view'), - 'name': 'Comparison Chart' - } - ] - - if 'ps' in request.session: # pragma: no cover - ps = PlannedSession.objects.get(id=int(request.session['ps'])) - breadcrumbs = [ - { - 'url': reverse('plannedsessions_view', - kwargs={'userid':userid}), - 'name': 'Sessions' - }, - { - 'url':reverse('plannedsession_view', - kwargs={ - 'userid':userid, - 'id':ps.id, - } - ), - 'name': ps.id - }, - { - 'url':reverse('plannedsession_compare_view', - kwargs={ - 'userid':userid, - 'id':ps.id, - } - ), - 'name': 'Compare' - } - ] - - - return render(request,'multicompare.html', - {'interactiveplot':script, - 'the_div':div, - 'breadcrumbs':breadcrumbs, - 'rower':r, - 'active':'nav-workouts', - 'promember':promember, - 'teamid':teamid, - 'chartform':chartform, - 'teams':get_my_teams(request.user), - }) - # List Workouts @login_required() def workouts_view(request,message='',successmessage='', - teamid=0,rankingonly=False,rowerid=0,userid=0): + teamid=0,rowerid=0,userid=0): startdate,enddate = get_dates_timeperiod(request,defaulttimeperiod='lastyear') request.session['referer'] = absolute(request)['PATH'] @@ -2333,8 +1959,6 @@ def workouts_view(request,message='',successmessage='', g_startdate = (timezone.now()-timedelta(days=15)) - if rankingonly: - workouts = workouts.exclude(rankingpiece=False) workoutsnohr = workouts.exclude(averagehr__isnull=False) for w in workoutsnohr: # pragma: no cover @@ -2357,7 +1981,7 @@ def workouts_view(request,message='',successmessage='', else: searchform = SearchForm() - paginator = Paginator(workouts,20) # show 25 workouts per page + paginator = Paginator(workouts,10) # show 25 workouts per page page = request.GET.get('page',1) try: @@ -2413,7 +2037,6 @@ def workouts_view(request,message='',successmessage='', 'enddate':enddate, 'announcements':announcements[0:4], 'team':theteam, - 'rankingonly':rankingonly, 'teams':get_my_teams(request.user), 'interactiveplot':script, 'the_div':div, @@ -6360,7 +5983,7 @@ def workout_course_view(request, id): ) if records: record = records[0] - else: + else: # pragma: no cover # create record record = VirtualRaceResult( userid = r.id, @@ -6392,7 +6015,7 @@ def workout_course_view(request, id): try: request.session['async_tasks'] += [(job.id,'check_race_course')] - except KeyError: + except KeyError: # pragma: no cover request.session['async_tasks'] = [(job.id,'check_race_course')] messages.info(request,'We are checking your time on the course in the background. You will receive an email when the check is complete. You can check the status here') diff --git a/static/css/rowsandall2.css b/static/css/rowsandall2.css index e4054cb8..62e92d7d 100644 --- a/static/css/rowsandall2.css +++ b/static/css/rowsandall2.css @@ -1,3 +1,5 @@ + + #main { background-color: transparent; -webkit-background-size: cover; @@ -320,6 +322,34 @@ th.rotate > div > span { margin: 2px; } +.divlines { + display: block; + overflow-x: hidden; + border-width: 1px 0 0 0; + border-color: #333 #333 #333 #333; + border-style: solid; + padding: 2px; + margin: 0px; +} + +.workoutcontainer { + display: grid; + grid-template-columns: 50px repeat(auto-fit, minmax(calc((100% - 100px)/4), 1fr)); + /* grid-template-columns: 50px repeat(auto-fit, minmax(100px, 1fr)) 50px; ????*/ + padding: 5px; +} + +.workoutelement { + margin-left: auto; + margin-right: auto; +} + +.divlines h3 { + font-size: 1.2em; + font-weight: bold; + padding: 0px; + margin: 0px; +} .whiteborder { border: solid 2px #aaa; } diff --git a/static/img/cd-icons.svg b/static/img/cd-icons.svg deleted file mode 100644 index a6e5b2a4..00000000 --- a/static/img/cd-icons.svg +++ /dev/null @@ -1,846 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - multi-level-accordion-menu/cd-icons.svg at master · CodyHouse/multi-level-accordion-menu - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - Skip to content -
    - - - - - - - - - - - - -
    - -
    - -
    - - -
    - - - -
    -
    -
    - - - - - - - - - - -
    -
    - -
      -
    • -
      - -
      - - - -
      -
      -
      - - Notifications -
      - - - -
      -
      -
      -
      -
    • - -
    • - -
      -
      - - - -
      -
      - - - -
      - -
    • - -
    • -
      - - - Fork - - -
      - -

      Where should we fork this repository?

      -
      -
      - -
      -

      If this dialog fails to load, you can visit the fork page directly.

      -
      -
      -
      -
      - - -
    • -
    - -

    - - /multi-level-accordion-menu - -

    - -
    - - - - -
    - -
    -
    - - - Permalink - - - - - -
    - -
    - - -
    - -
    -
    - - Switch branches/tags -
    - -
    -
    - -
    -
    - -
    -
    - - - -
    -
    - - -
    - -
    Nothing to show
    -
    - -
    -
    -
    - -
    - - Find file - - - Copy path - -
    - -
    - - - -
    - Fetching contributors… -
    - -
    - - Cannot retrieve contributors at this time -
    -
    - - -
    -
    -
    - - -
    - Raw - Blame - History -
    - - - - - -
    - -
    -
    - -
    - -
    - 27 lines (26 sloc) - - 1.68 KB -
    -
    - - - -
    - -
    -
    - -
    Sorry, something went wrong. Reload?
    -
    Sorry, we cannot display this file.
    -
    Sorry, this file is invalid so it cannot be displayed.
    - -
    -
    - -
    - -
    - -
    - - -
    - - -
    -
    - - -
    - -
    - -
    -
    - -
    - - - - - - -
    - - - You can’t perform that action at this time. -
    - - - - - - - - - -
    - - You signed in with another tab or window. Reload to refresh your session. - You signed out in another tab or window. Reload to refresh your session. -
    - - - - - - -
    - Press h to open a hovercard with more details. -
    - - - - - diff --git a/templates/newbase.html b/templates/newbase.html index 5273af76..b05a4421 100644 --- a/templates/newbase.html +++ b/templates/newbase.html @@ -46,7 +46,7 @@ - + {% block meta %} {% endblock %}