Rename workout model attributes

'comment' is renamed to 'name' and a new field 'description' is now available
for actual longer descriptions if needed

Closes #666
This commit is contained in:
Roland Geider
2021-05-05 11:27:33 +02:00
parent 4220348fb0
commit b0ec10a5cd
17 changed files with 494 additions and 374 deletions

View File

@@ -11,6 +11,7 @@ For a live system, refer to the project's site: <https://wger.de/>
![Workout plan](https://raw.githubusercontent.com/wger-project/wger/master/wger/software/static/images/workout.png)
## Installation
These are the basic steps to install and run the application locally on a Linux

View File

@@ -20,7 +20,16 @@ Upgrade steps from 2.0:
🧰 Maintenance:
*
* Changes to the REST API:
+ /exerciseimage/
- ``exercise`` was renamed to ``exercise_base`` (was pointing there anyway)
+ /workout/
- ``comment`` was renamed to name
- field ``description`` was added, for longer descriptions
* `#666`_,
.. _#666: https://github.com/wger-project/wger/issues/666
2.0
@@ -108,7 +117,7 @@ Upgrade steps from 1.9:
.. _@jeevikaghosh: https://github.com/jeevikaghosh
.. _@bradsk88: https://github.com/bradsk88
.. _@Sidrah-Madiha: https://github.com/Sidrah-Madiha
.. _@calvinrw : https://github.com/calvinrw
.. _@calvinrw: https://github.com/calvinrw
.. _#246: https://github.com/wger-project/wger/issues/246

View File

@@ -83,7 +83,7 @@ def create_demo_entries(user):
#
setting_list = []
weight_log = []
workout = Workout(user=user, comment=_('Sample workout'))
workout = Workout(user=user, name=_('Sample workout'))
workout.save()
monday = DaysOfWeek.objects.get(pk=1)
wednesday = DaysOfWeek.objects.get(pk=3)
@@ -338,11 +338,11 @@ def create_demo_entries(user):
#
# create some empty workouts to fill the list
workout2 = Workout(user=user, comment=_('Placeholder workout nr {0} for schedule').format(1))
workout2 = Workout(user=user, name=_('Placeholder workout nr {0} for schedule').format(1))
workout2.save()
workout3 = Workout(user=user, comment=_('Placeholder workout nr {0} for schedule').format(2))
workout3 = Workout(user=user, name=_('Placeholder workout nr {0} for schedule').format(2))
workout3.save()
workout4 = Workout(user=user, comment=_('Placeholder workout nr {0} for schedule').format(3))
workout4 = Workout(user=user, name=_('Placeholder workout nr {0} for schedule').format(3))
workout4.save()
schedule = Schedule()

View File

@@ -1,69 +1,83 @@
{% load i18n static wger_extras thumbnail %}
<script>
$(document).ready(function() {
$(document).ready(function () {
// Call the setup function to allow the sets to be sortable again after loading this
// view via AJAX
wgerSetupSortable();
// Call the setup function to allow the sets to be sortable again after loading this
// view via AJAX
wgerSetupSortable();
// Init the modal dialog to edit the exercise
wgerFormModalDialog();
// Init the modal dialog to edit the exercise
wgerFormModalDialog();
})
})
</script>
<table class="table table-bordered workout-table" id="table-day-{{ day.obj.id }}" data-id="{{ day.obj.id }}">
<thead class="thead-light">
<table class="table table-bordered workout-table" id="table-day-{{ day.obj.id }}"
data-id="{{ day.obj.id }}">
<thead class="thead-light">
<tr id="day-{{ day.obj.id }}">
<th colspan="2">
{{ day.days_of_week.text }} {{ day.obj.description }}
{% if editable %}
<div class="float-right">
<div class="dropdown">
<button class="btn btn-sm dropdown-toggle " type="button" id="dropdownMenuDay{{day.obj.id}}" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
<span class="{% fa_class 'cog' %}"></span>
</button>
<div class="dropdown-menu dropdown-menu-right" aria-labelledby="dropdownMenuDay{{day.obj.id}}">
<a href="{% url 'manager:day:log' day.obj.id %}" class="dropdown-item">
<span class="{% fa_class 'chart-line' %}"></span>
{% translate 'Add weight log' %}
</a>
<a href="{% url 'manager:day:edit' day.obj.id %}" class="wger-modal-dialog dropdown-item">
<span class="{% fa_class 'edit' %}"></span>
{% translate 'Edit' %}
</a>
<div class="dropdown-divider"></div>
<a href="{% url 'manager:day:delete' day.obj.id %}" class="dropdown-item">
<span class="{% fa_class 'trash' %}"></span>
{% translate 'Delete' %}
</a>
<div class="float-right">
<div class="dropdown">
<button class="btn btn-sm dropdown-toggle " type="button"
id="dropdownMenuDay{{ day.obj.id }}" data-toggle="dropdown"
aria-haspopup="true" aria-expanded="false">
<span class="{% fa_class 'cog' %}"></span>
</button>
<div class="dropdown-menu dropdown-menu-right"
aria-labelledby="dropdownMenuDay{{ day.obj.id }}">
<a href="{% url 'manager:day:log' day.obj.id %}" class="dropdown-item">
<span class="{% fa_class 'chart-line' %}"></span>
{% translate 'Add weight log' %}
</a>
<a href="{% url 'manager:day:edit' day.obj.id %}"
class="wger-modal-dialog dropdown-item">
<span class="{% fa_class 'edit' %}"></span>
{% translate 'Edit' %}
</a>
<div class="dropdown-divider"></div>
<a href="{% url 'manager:day:delete' day.obj.id %}"
class="dropdown-item">
<span class="{% fa_class 'trash' %}"></span>
{% translate 'Delete' %}
</a>
</div>
</div>
</div>
</div>
</div>
{% endif %}
<h4>{{ day.obj.description }}</h4>
{{ day.days_of_week.text }}
</th>
</tr>
</thead>
<tbody>
{% for set in day.set_list %}
{% for set in day.set_list %}
<tr data-id="{{ set.obj.id }}" id="set-{{ set.obj.id }}">
<td style="width: 15%;border-right-width: 0px;">
<td style="width: 15%;border-right-width: 0;">
<span>#{{ forloop.counter }}</span>
{% if editable %}
<div class="dropdown float-right">
<button class="btn btn-link btn-sm btn-block dropdown-toggle " type="button" id="dropdownMenuSet{{set.obj.id}}" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
<button class="btn btn-link btn-sm btn-block dropdown-toggle " type="button"
id="dropdownMenuSet{{ set.obj.id }}" data-toggle="dropdown"
aria-haspopup="true" aria-expanded="false">
</button>
<div class="dropdown-menu dropdown-menu-right" aria-labelledby="dropdownMenuSet{{set.obj.id}}">
<a href="{% url 'manager:set:edit' set.obj.id %}" class="wger-modal-dialog dropdown-item">
<span class="{% fa_class 'edit' %}"></span>
{% translate 'Edit' %}
<div class="dropdown-menu dropdown-menu-right"
aria-labelledby="dropdownMenuSet{{ set.obj.id }}">
<a href="{% url 'manager:set:edit' set.obj.id %}"
class="wger-modal-dialog dropdown-item">
<span class="{% fa_class 'edit' %}"></span>
{% translate 'Edit' %}
</a>
<div class="dropdown-divider"></div>
<a href="{% url 'manager:set:delete' set.obj.id %}" class="dropdown-item">
<a href="{% url 'manager:set:delete' set.obj.id %}"
class="dropdown-item">
<span class="{% fa_class 'trash' %}"></span>
{% translate 'Delete' %}
</a>
@@ -71,7 +85,7 @@ $(document).ready(function() {
</div>
{% if false and day.set_list|length > 1 %}
<span class="editoptions">
<span class="editoptions">
<span class="{% fa_class 'bars' %} dragndrop-handle"></span>
<br>
</span>
@@ -81,67 +95,67 @@ $(document).ready(function() {
<td style="border-left-width: 0px;">
<div class="exercise-list">
{% for exercise in set.exercise_list %}
<div id="exercise-{{ exercise.obj.id }}" class="ajax-set-edit-target">
<div class="media">
<div id="exercise-{{ exercise.obj.id }}" class="ajax-set-edit-target">
<div class="media">
<div style="width: 64px; height: 64px;">
<a href="{{exercise.obj.get_absolute_url}}" >
{% if exercise.obj.main_image %}
<img class="img-fluid"
src="{{ exercise.obj.main_image.image|thumbnail_url:'small' }}"
alt="{{exercise.obj}}"
style="max-width: 100%; max-height: 100%;">
{% else %}
<img class="img-fluid"
src="{% static 'images/icons/image-placeholder.svg' %}"
alt="{% translate 'Placeholder image for exercise' %}"
style="opacity: 0.4;">
{% endif %}
</a>
</div>
<div class="media-body ml-2">
<p class="media-heading h5">
{{ exercise.obj.name }}
</p>
<p>{{exercise.setting_text}}</p>
{% if editable %}
{% if not exercise.setting_obj_list %}
<p>
{% translate "This exercise has no repetitions." %}<br>
<a href="{% url 'manager:set:edit' set.obj.id %}" class="wger-modal-dialog">
{% translate "Edit them now."%}
<div style="width: 64px; height: 64px;">
<a href="{{ exercise.obj.get_absolute_url }}">
{% if exercise.obj.main_image %}
<img class="img-fluid"
src="{{ exercise.obj.main_image.image|thumbnail_url:'small' }}"
alt="{{ exercise.obj }}"
style="max-width: 100%; max-height: 100%;">
{% else %}
<img class="img-fluid"
src="{% static 'images/icons/image-placeholder.svg' %}"
alt="{% translate 'Placeholder image for exercise' %}"
style="opacity: 0.4;">
{% endif %}
</a>
</p>
{% endif %}
</div>
{% if exercise.comment_list %}
<p class="text-muted exercise-comments">
{% for comment in exercise.comment_list %}
{{comment}}<br>
{% endfor %}
</p>
{% endif %}
{% endif %}
<div class="media-body ml-2">
<p class="media-heading h5">
{{ exercise.obj.name }}
</p>
<p>{{ exercise.setting_text }}</p>
{% if editable %}
{% if not exercise.setting_obj_list %}
<p>
{% translate "This exercise has no repetitions." %}<br>
<a href="{% url 'manager:set:edit' set.obj.id %}"
class="wger-modal-dialog">
{% translate "Edit them now." %}
</a>
</p>
{% endif %}
{% if exercise.comment_list %}
<p class="text-muted exercise-comments">
{% for comment in exercise.comment_list %}
{{ comment }}<br>
{% endfor %}
</p>
{% endif %}
{% endif %}
</div>
</div>
</div>
</div>
{% endfor %} <!--for exercise in set-->
</div>
</td>
</tr>
{% endfor %} <!--for set in day-->
{% if editable %}
{% endfor %} <!--for set in day-->
{% if editable %}
<tr>
<td colspan="2" class="py-0">
<a href="{% url 'manager:set:add' day.obj.id %}"
class="wger-modal-dialog btn btn-link btn-block">{% translate "Add exercises to this workout day" %}</a>
</td>
</tr>
{% endif %}
{% endif %}
</tbody>
</table>

View File

@@ -77,7 +77,7 @@ class ExercisecommentsTestCase(WgerTestCase):
# Comments are loaded
comments = exercise_1.exercisecomment_set.all()
comment_1 = comments[0]
comment_1: ExerciseComment = comments[0]
self.assertEqual(comment_1.id, 1)
self.assertEqual(comment_1.comment, "test 123")
self.assertEqual(len(comments), 1)

View File

@@ -61,7 +61,8 @@ class WorkoutViewSet(viewsets.ModelViewSet):
serializer_class = WorkoutSerializer
is_private = True
ordering_fields = '__all__'
filterset_fields = ('comment',
filterset_fields = ('name',
'description',
'creation_date')
def get_queryset(self):

View File

@@ -3,27 +3,30 @@
"pk": 1,
"model": "manager.workout",
"fields": {
"comment": "A test workout",
"name": "A test workout",
"user": 1,
"creation_date": "2012-11-01"
"creation_date": "2012-11-01",
"description": "Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna"
}
},
{
"pk": 2,
"model": "manager.workout",
"fields": {
"comment": "Another test workout",
"name": "Another test workout",
"user": 1,
"creation_date": "2012-11-10"
"creation_date": "2012-11-10",
"description": "The wild boar (Sus scrofa), also known as the \"wild swine\", \"common wild pig\", or simply \"wild pig\", is a suid native to much of Eurasia and North Africa"
}
},
{
"pk": 3,
"model": "manager.workout",
"fields": {
"comment": "My test workout",
"name": "My test workout",
"user": 2,
"creation_date": "2012-11-20"
"creation_date": "2012-11-20",
"description": ""
}
},

View File

@@ -73,9 +73,14 @@ class WorkoutForm(ModelForm):
class WorkoutCopyForm(Form):
comment = CharField(max_length=100,
help_text=_('The goal or description of the new workout.'),
required=False)
name = CharField(max_length=100,
help_text=_('The name of the workout'),
required=False)
description = CharField(max_length=1000,
help_text=_("A short description or goal of the workout. For "
"example 'Focus on back' or 'Week 1 of program xy'."),
widget=widgets.Textarea,
required=False)
class DayForm(ModelForm):
@@ -111,7 +116,7 @@ class SetForm(ModelForm):
class SettingForm(ModelForm):
class Meta:
model = Setting
exclude = ('set', 'exercise', 'order', 'comment')
exclude = ('set', 'exercise', 'order', 'name')
class WorkoutLogForm(ModelForm):

View File

@@ -0,0 +1,41 @@
# Generated by Django 3.1.8 on 2021-04-30 12:49
import django.core.validators
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('manager', '0011_remove_set_exercises'),
]
operations = [
migrations.RenameField(
model_name='workout',
old_name='comment',
new_name='name'
),
migrations.AddField(
model_name='workout',
name='description',
field=models.TextField(blank=True,
help_text="A short description or goal of the workout. For "
"example 'Focus on back' or 'Week 1 of program xy'.",
max_length=1000, verbose_name='Description'),
),
migrations.AlterField(
model_name='workout',
name='name',
field=models.CharField(blank=True,
help_text='The name of the workout',
max_length=100,
verbose_name='Name'),
),
migrations.AlterField(
model_name='setting',
name='reps',
field=models.IntegerField(validators=[django.core.validators.MinValueValidator(0),
django.core.validators.MaxValueValidator(600)],
verbose_name='Reps'),
),
]

View File

@@ -80,11 +80,17 @@ class Workout(models.Model):
ordering = ["-creation_date", ]
creation_date = models.DateField(_('Creation date'), auto_now_add=True)
comment = models.CharField(verbose_name=_('Description'),
max_length=100,
blank=True,
help_text=_("A short description or goal of the workout. For "
"example 'Focus on back' or 'Week 1 of program xy'."))
name = models.CharField(verbose_name=_('Name'),
max_length=100,
blank=True,
help_text=_("The name of the workout"))
description = models.TextField(verbose_name=_('Description'),
max_length=1000,
blank=True,
help_text=_("A short description or goal of the workout. For "
"example 'Focus on back' or 'Week 1 of program "
"xy'."))
user = models.ForeignKey(User, verbose_name=_('User'), on_delete=models.CASCADE)
def get_absolute_url(self):
@@ -97,8 +103,8 @@ class Workout(models.Model):
"""
Return a more human-readable representation
"""
if self.comment:
return "{0}".format(self.comment)
if self.name:
return self.name
else:
return "{0} ({1})".format(_('Workout'), self.creation_date)
@@ -361,7 +367,7 @@ class ScheduleStep(models.Model):
"""
Return a more human-readable representation
"""
return self.workout.comment
return self.workout.name
def get_dates(self):
"""

View File

@@ -40,12 +40,6 @@
{# Content #}
{# #}
{% block content %}
{% if workout.comment %}
<p>
<strong>{% translate "Goal" %}:</strong> {{workout.comment}}
</p>
{% endif %}
{% for day in workout.canonical_representation.day_list %}
<h4>{{ day.obj.description }}</h4>

View File

@@ -16,7 +16,7 @@
{# #}
{# Title #}
{# #}
{% block title %}{% translate "Workout" %} {{ workout.creation_date }}{% endblock %}
{% block title %}{% translate "Workout" %}{% endblock %}
{# #}
@@ -52,8 +52,12 @@ $(document).ready(function () {
{% block content %}
{% if workout.comment %}
<h4>{{workout.comment}}</h4>
{% if workout.name %}
<h4>{{workout.name }}</h4>
{% endif %}
{% if workout.description %}
<p>{{ workout.description }}</p>
{% endif %}
{% for day in workout.canonical_representation.day_list %}

View File

@@ -47,7 +47,7 @@ class CopyWorkoutTestCase(WgerTestCase):
# Copy the workout
count_before = Workout.objects.count()
self.client.post(reverse('manager:workout:copy', kwargs={'pk': '3'}),
{'comment': 'A copied workout'})
{'name': 'A copied workout'})
count_after = Workout.objects.count()
if not owner:

View File

@@ -150,7 +150,7 @@ class EditWorkoutTestCase(WgerEditTestCase):
pk = 3
user_success = 'test'
user_fail = 'admin'
data = {'comment': 'A new comment'}
data = {'name': 'A new comment'}
class WorkoutOverviewTestCase(WgerTestCase):
@@ -192,7 +192,7 @@ class WorkoutModelTestCase(WgerTestCase):
self.assertEqual('{0}'.format(workout),
'{0} ({1})'.format('Workout', datetime.date.today()))
workout.comment = 'my description'
workout.name = 'my description'
self.assertEqual('{0}'.format(workout), 'my description')
@@ -204,4 +204,4 @@ class WorkoutApiTestCase(api_base_test.ApiBaseResourceTestCase):
resource = Workout
private_resource = True
special_endpoints = ('canonical_representation',)
data = {'comment': 'A new comment'}
data = {'name': 'A new comment'}

View File

@@ -93,11 +93,14 @@ def workout_log(request, id, images=False, comments=False, uidb64=None, token=No
elements.append(Spacer(10 * cm, 0.5 * cm))
# Set the title
p = Paragraph('<para align="center"><strong>%(description)s</strong></para>' %
{'description': workout},
p = Paragraph(f'<para align="center"><strong>{workout.name}</strong></para>',
styleSheet["HeaderBold"])
elements.append(p)
elements.append(Spacer(10 * cm, 1.5 * cm))
elements.append(Spacer(10 * cm, 0.5 * cm))
if workout.description:
p = Paragraph(f'<para align="center">{workout.description}</para>')
elements.append(p)
elements.append(Spacer(10 * cm, 1.5 * cm))
# Iterate through the Workout and render the training days
for day in workout.canonical_representation['day_list']:

View File

@@ -146,7 +146,7 @@ def copy_workout(request, pk):
workout_copy = copy.copy(workout)
workout_copy.pk = None
workout_copy.comment = workout_form.cleaned_data['comment']
workout_copy.name = workout_form.cleaned_data['name']
workout_copy.user = request.user
workout_copy.save()
@@ -180,7 +180,7 @@ def copy_workout(request, pk):
return HttpResponseRedirect(reverse('manager:workout:view',
kwargs={'pk': workout_copy.id}))
else:
workout_form = WorkoutCopyForm({'comment': workout.comment})
workout_form = WorkoutCopyForm({'name': workout.name, 'description': workout.description})
workout_form.helper = FormHelper()
workout_form.helper.form_id = slugify(request.path)
workout_form.helper.form_method = 'post'
@@ -193,7 +193,7 @@ def copy_workout(request, pk):
template_data.update(csrf(request))
template_data['title'] = _('Copy workout')
template_data['form'] = workout_form
template_data['form_fields'] = [workout_form['comment']]
template_data['form_fields'] = [workout_form['name']]
template_data['submit_text'] = _('Copy')
return render(request, 'form.html', template_data)
@@ -217,7 +217,7 @@ class WorkoutDeleteView(WgerDeleteMixin, LoginRequiredMixin, DeleteView):
"""
model = Workout
fields = ('comment',)
fields = ('name',)
success_url = reverse_lazy('manager:workout:overview')
messages = gettext_lazy('Successfully deleted')

View File

@@ -9,31 +9,30 @@
{% block opengraph %}
{{ block.super }}
<meta property="og:title" content="{% translate 'Nutrition plan' %}">
<meta property="og:description" content="{{ plan }} / {{owner_user.username}}">
<meta property="og:description" content="{{ plan }} / {{ owner_user.username }}">
{% endblock %}
{# #}
{# Title #}
{# #}
{% block title %}{% translate "Nutrition plan" %} {{ plan.creation_date}}{% endblock %}
{% block title %}{% translate "Nutrition plan" %}{% endblock %}
{# #}
{# Header #}
{# #}
{% block header %}
<script>
$(document).ready(function () {
wgerDrawNutritionDiaryChart({{ plan.pk }});
});
<script>
$(document).ready(function () {
wgerDrawNutritionDiaryChart({{ plan.pk }});
});
function wgerCustomModalInit()
{
// Init the autocompleter after loading the modal dialog
wgerInitIngredientAutocompleter();
}
</script>
function wgerCustomModalInit() {
// Init the autocompleter after loading the modal dialog
wgerInitIngredientAutocompleter();
}
</script>
{% endblock %}
@@ -42,160 +41,188 @@ function wgerCustomModalInit()
{# Content #}
{# #}
{% block content %}
{% if plan.description %}
<h4>{{plan.description}}</h4>
{% endif %}
{% if plan.description %}
<h4>{{ plan.description }}</h4>
{% endif %}
<div class="table-responsive">
<table class="table table-bordered">
<thead>
<tr style="background: #E0E0E0;">
<th>{% translate "Meal" %}</th>
<th>{% translate "Contents" %}</th>
<th class="align-right">{% translate "Energy" %}</th>
<th class="align-right">{% translate "Protein" %}</th>
<th class="align-right">{% translate "Carbohydrates" %}</th>
<th class="align-right">{% translate "Fat" %}</th>
</tr>
</thead>
<tbody>
<tr>
<td colspan="2"></td>
<td class="align-right">{% translate 'kcal' %} / {% translate 'kJ' %}</td>
<td class="align-right">{% trans_weight_unit 'g' owner_user %}</td>
<td class="align-right">{% trans_weight_unit 'g' owner_user %}</td>
<td class="align-right">{% trans_weight_unit 'g' owner_user %}</td>
</tr>
{% for meal in plan.meal_set.select_related %}
<tr>
<td {% if meal.mealitem_set.count %}rowspan="{{meal.mealitem_set.count|add:1}}"{% endif %}>
<strong>
{% translate "Nr."%} {{ forloop.counter }}
{% if meal.time %} &ndash; {{meal.time|time:"H:i"}}{% endif %}
</strong>
<div class="table-responsive">
<table class="table table-bordered">
<thead>
<tr style="background: #E0E0E0;">
<th>{% translate "Contents" %}</th>
<th class="align-right">{% translate "Energy" %}</th>
<th class="align-right">{% translate "Protein" %}</th>
<th class="align-right">{% translate "Carbohydrates" %}</th>
<th class="align-right">{% translate "Fat" %}</th>
</tr>
</thead>
<tbody>
<tr>
<td colspan="1"></td>
<td class="align-right">{% translate 'kcal' %} / {% translate 'kJ' %}</td>
<td class="align-right">{% trans_weight_unit 'g' owner_user %}</td>
<td class="align-right">{% trans_weight_unit 'g' owner_user %}</td>
<td class="align-right">{% trans_weight_unit 'g' owner_user %}</td>
</tr>
{% for meal in plan.meal_set.select_related %}
<tr>
<td colspan="6">
{% if is_owner %}
<div class="dropdown float-right">
<button type="button"
class="btn btn-link btn-block dropdown-toggle btn-xs"
data-toggle="dropdown"></button>
<div class="dropdown-menu dropdown-menu-right" role="menu">
<a href="{% url 'nutrition:log:log_meal' meal.id %}"
class="dropdown-item">
<span class="{% fa_class 'chart-line' %}"></span>
{% translate 'Log this meal' %}
</a>
<a href="{% url 'nutrition:meal_item:add' meal.id %}"
class="wger-modal-dialog edit-meal dropdown-item">
<span class="{% fa_class 'plus' %}"></span>
{% translate 'Add ingredient to meal' %}
</a>
<a href="{% url 'nutrition:meal:edit' meal.id %}"
class="wger-modal-dialog dropdown-item">
<span class="{% fa_class 'edit' %}"></span>
{% translate 'Edit' %}
</a>
<div class="dropdown-divider"></div>
<a href="{% url 'nutrition:meal:delete' meal.id %}"
class="dropdown-item">
<span class="{% fa_class 'trash' %}"></span>
{% translate 'Delete' %}
</a>
</div>
</div>
{% endif %}
{% if is_owner %}
<div class="dropdown">
<button type="button" class="btn btn-link btn-block dropdown-toggle btn-xs" data-toggle="dropdown"></button>
<div class="dropdown-menu dropdown-menu-right" role="menu">
<a href="{% url 'nutrition:log:log_meal' meal.id %}" class="dropdown-item">
<span class="{% fa_class 'chart-line' %}"></span>
{% translate 'Log this meal' %}
</a>
<a href="{% url 'nutrition:meal_item:add' meal.id %}" class="wger-modal-dialog edit-meal dropdown-item">
<span class="{% fa_class 'plus' %}"></span>
{% translate 'Add ingredient to meal' %}
</a>
<a href="{% url 'nutrition:meal:edit' meal.id %}" class="wger-modal-dialog dropdown-item">
<span class="{% fa_class 'edit' %}"></span>
{% translate 'Edit' %}
</a>
<div class="dropdown-divider"></div>
<a href="{% url 'nutrition:meal:delete' meal.id %}" class="dropdown-item">
<span class="{% fa_class 'trash' %}"></span>
{% translate 'Delete' %}
</a>
</div>
</div>
{% endif %}
</td>
{% for item in meal.mealitem_set.select_related %}
<td>
{% if item.get_unit_type == MEALITEM_WEIGHT_GRAM %}{{ item.amount|floatformat:"0" }}g
{% else %}
{{ item.amount|floatformat:"0" }} × {{ item.weight_unit.unit.name }}
{% endif %}
{{ item.ingredient.name }}
<h4>{% if meal.time %}{{ meal.time|time:"H:i" }}{% endif %}</h4>
</td>
</tr>
<tr>
{% for item in meal.mealitem_set.select_related %}
<td>
{% if item.get_unit_type == MEALITEM_WEIGHT_GRAM %}
{{ item.amount|floatformat:"0" }}g
{% else %}
{{ item.amount|floatformat:"0" }} × {{ item.weight_unit.unit.name }}
{% endif %}
{{ item.ingredient.name }}
{% if is_owner %}
<div class="dropdown float-right">
<button type="button"
class="btn btn-link dropdown-toggle btn-xs"
data-toggle="dropdown"></button>
<div class="dropdown-menu dropdown-menu-right" role="menu">
<a href="{% url 'nutrition:meal_item:edit' item.id %}"
class="wger-modal-dialog edit-meal edit-mealitem dropdown-item">
<span class="{% fa_class 'edit' %}"></span>
{% translate 'Edit' %}
</a>
<div class="dropdown-divider"></div>
<a href="{% url 'nutrition:meal_item:delete' item.id %}"
class="delete-mealitem dropdown-item">
<span class="{% fa_class 'trash' %}"></span>
{% translate 'Delete' %}
</a>
</div>
</div>
<span class="editoptions float-right"></span>
{% endif %}
</td>
<td class="align-right">{{ item.get_nutritional_values.energy|floatformat:1 }}
/
{{ item.get_nutritional_values.energy_kilojoule|floatformat:1 }}</td>
<td class="align-right">{{ item.get_nutritional_values.protein|floatformat:1 }}</td>
<td class="align-right">{{ item.get_nutritional_values.carbohydrates|floatformat:1 }}</td>
<td class="align-right">{{ item.get_nutritional_values.fat|floatformat:1 }}</td>
</tr>
{% empty %}
{% if is_owner %}
<td colspan="6">
<a href="{% url 'nutrition:meal_item:add' meal.id %}"
title="{% translate 'Add one now.' %}"
class="wger-modal-dialog edit-meal btn btn-link btn-block">
{% translate "No items for this meal." %}
{% translate "Add one now." %}
</a>
</td>
{% endif %}
{% endfor %}
<tr>
<td class="align-right">Σ</td>
<td class="align-right">
<span class="text-muted">
{{ meal.get_nutritional_values.energy|floatformat:1 }} /
{{ meal.get_nutritional_values.energy_kilojoule|floatformat:1 }}
</span>
</td>
<td class="align-right">
<span class="text-muted">
{{ meal.get_nutritional_values.protein|floatformat:1 }}
</span>
</td>
<td class="align-right">
<span class="text-muted">
{{ meal.get_nutritional_values.carbohydrates|floatformat:1 }}
</span>
</td>
<td class="align-right">
<span class="text-muted">
{{ meal.get_nutritional_values.fat|floatformat:1 }}
</span>
</td>
</tr>
{% empty %}
{% if is_owner %}
<div class="dropdown float-right">
<button type="button" class="btn btn-link dropdown-toggle btn-xs" data-toggle="dropdown"></button>
<div class="dropdown-menu dropdown-menu-right" role="menu">
<a href="{% url 'nutrition:meal_item:edit' item.id %}" class="wger-modal-dialog edit-meal edit-mealitem dropdown-item">
<span class="{% fa_class 'edit' %}"></span>
{% translate 'Edit' %}
</a>
<div class="dropdown-divider"></div>
<a href="{% url 'nutrition:meal_item:delete' item.id %}" class="delete-mealitem dropdown-item">
<span class="{% fa_class 'trash' %}"></span>
{% translate 'Delete' %}
</a>
</div>
</div>
<span class="editoptions float-right">
</span>
<tr>
<td colspan="6">
<a href="{% url 'nutrition:meal:add' plan.id %}"
class="wger-modal-dialog btn btn-link btn-block">
{% translate "No meals for this plan." %}
{% translate "Add one now." %}
</a>
</td>
</tr>
{% endif %}
</td>
<td class="align-right">{{item.get_nutritional_values.energy|floatformat:1}} /
{{item.get_nutritional_values.energy_kilojoule|floatformat:1}}</td>
<td class="align-right">{{item.get_nutritional_values.protein|floatformat:1}}</td>
<td class="align-right">{{item.get_nutritional_values.carbohydrates|floatformat:1}}</td>
<td class="align-right">{{item.get_nutritional_values.fat|floatformat:1}}</td>
</tr>
{% empty %}
{% endfor %}
{% if is_owner %}
<td colspan="6">
<a href="{% url 'nutrition:meal_item:add' meal.id %}"
title="{% translate 'Add one now.' %}"
class="wger-modal-dialog edit-meal btn btn-link btn-block">
{% translate "No items for this meal." %}
{% translate "Add one now."%}
</a>
</td>
<tr>
<td colspan="6" class="py-0"><a
href="{% url 'nutrition:log:log_plan' plan.id %}"
class="btn btn-link btn-block">
{% translate "Log this Plan" %}</a></td>
</tr>
<tr>
<td colspan="6" class="py-0">
<a href="{% url 'nutrition:meal:add' plan.id %}"
class="wger-modal-dialog btn btn-link btn-block">
{% translate "Add a new meal" %}
</a>
</td>
<tr>
{% endif %}
{% endfor %}
</tbody>
</table>
</div>
<tr>
<td></td>
<td class="align-right">{{meal.get_nutritional_values.energy|floatformat:1}} /
{{meal.get_nutritional_values.energy_kilojoule|floatformat:1}}</td>
<td class="align-right">{{meal.get_nutritional_values.protein|floatformat:1}}</td>
<td class="align-right">{{meal.get_nutritional_values.carbohydrates|floatformat:1}}</td>
<td class="align-right">{{meal.get_nutritional_values.fat|floatformat:1}}</td>
</tr>
{% empty %}
{% if is_owner %}
<tr>
<td colspan="6">
<a href="{% url 'nutrition:meal:add' plan.id %}" class="wger-modal-dialog btn btn-link btn-block">
{% translate "No meals for this plan." %}
{% translate "Add one now." %}
</a>
</td>
</tr>
<h4>{% translate "Nutritional data" %}</h4>
{% if weight_entry %}
<h6>
{% blocktranslate with date=weight_entry.date weight=weight_entry.weight trimmed %}
Based on the weight entry dated {{ date }} ({{ weight }})
{% endblocktranslate %}
</h6>
{% endif %}
{% endfor %}
{% if is_owner %}
<tr>
<td colspan="6" class="py-0"><a href="{% url 'nutrition:log:log_plan' plan.id %}"
class="btn btn-link btn-block">
{% translate "Log this Plan" %}</a></td>
</tr>
<tr>
<td colspan="6" class="py-0">
<a href="{% url 'nutrition:meal:add' plan.id %}"
class="wger-modal-dialog btn btn-link btn-block">
{% translate "Add a new meal" %}
</a>
</td>
<tr>
{% endif %}
</tbody>
</table>
</div>
<h4>{% translate "Nutritional data" %}</h4>
{% if weight_entry %}
<h6>
{% blocktranslate with date=weight_entry.date weight=weight_entry.weight trimmed %}
Based on the weight entry dated {{date}} ({{weight}})
{% endblocktranslate %}
</h6>
{% endif %}
<table class="table table-sm">
<thead>
<table class="table table-sm">
<thead>
<tr>
<th>{% translate "Macronutrients" %}</th>
<th class="align-right">{% translate "Total" %}</th>
@@ -208,42 +235,44 @@ function wgerCustomModalInit()
{% endif %}
</th>
</tr>
</thead>
<tbody>
</thead>
<tbody>
<tr>
<td>{% translate "Energy" %}</td>
<td class="align-right">{{nutritional_data.total.energy|floatformat:0}} {% translate "kcal" %} /
{{nutritional_data.total.energy_kilojoule|floatformat:0}} {% translate "kJ" %}</td>
<td class="align-right">{{ nutritional_data.total.energy|floatformat:0 }} {% translate "kcal" %}
/
{{ nutritional_data.total.energy_kilojoule|floatformat:0 }} {% translate "kJ" %}</td>
<td></td>
<td></td>
</tr>
<tr>
<td>{% translate "Protein" %}</td>
<td class="align-right">{{nutritional_data.total.protein|floatformat:1}} {% trans_weight_unit 'g' owner_user %}</td>
<td class="align-right">{{nutritional_data.percent.protein|floatformat:1}} %</td>
<td class="align-right">{{nutritional_data.per_kg.protein|floatformat:2}}</td>
<td class="align-right">{{ nutritional_data.total.protein|floatformat:1 }} {% trans_weight_unit 'g' owner_user %}</td>
<td class="align-right">{{ nutritional_data.percent.protein|floatformat:1 }} %</td>
<td class="align-right">{{ nutritional_data.per_kg.protein|floatformat:2 }}</td>
</tr>
<tr>
<td>{% translate "Carbohydrates" %}</td>
<td class="align-right">{{nutritional_data.total.carbohydrates|floatformat:1}} {% trans_weight_unit 'g' owner_user %}</td>
<td class="align-right">{{nutritional_data.percent.carbohydrates|floatformat:1}} %</td>
<td class="align-right">{{nutritional_data.per_kg.carbohydrates|floatformat:2}}</td>
<td class="align-right">{{ nutritional_data.total.carbohydrates|floatformat:1 }} {% trans_weight_unit 'g' owner_user %}</td>
<td class="align-right">{{ nutritional_data.percent.carbohydrates|floatformat:1 }} %
</td>
<td class="align-right">{{ nutritional_data.per_kg.carbohydrates|floatformat:2 }}</td>
</tr>
<tr>
<td class="pl-4">{% translate "Sugar content in carbohydrates" %}</td>
<td class="align-right">{{nutritional_data.total.carbohydrates_sugar|floatformat:1}} {% trans_weight_unit 'g' owner_user %}</td>
<td class="align-right">{{ nutritional_data.total.carbohydrates_sugar|floatformat:1 }} {% trans_weight_unit 'g' owner_user %}</td>
<td></td>
<td></td>
</tr>
<tr>
<td>{% translate "Fat" %}</td>
<td class="align-right">{{nutritional_data.total.fat|floatformat:1}} {% trans_weight_unit 'g' owner_user %}</td>
<td class="align-right">{{nutritional_data.percent.fat|floatformat:1}} %</td>
<td class="align-right">{{nutritional_data.per_kg.fat|floatformat:2}}</td>
<td class="align-right">{{ nutritional_data.total.fat|floatformat:1 }} {% trans_weight_unit 'g' owner_user %}</td>
<td class="align-right">{{ nutritional_data.percent.fat|floatformat:1 }} %</td>
<td class="align-right">{{ nutritional_data.per_kg.fat|floatformat:2 }}</td>
</tr>
<tr>
<td class="pl-4">{% translate "Saturated fat content in fats" %}</td>
<td class="align-right">{{nutritional_data.total.fat_saturated|floatformat:1}} {% trans_weight_unit 'g' owner_user %}</td>
<td class="align-right">{{ nutritional_data.total.fat_saturated|floatformat:1 }} {% trans_weight_unit 'g' owner_user %}</td>
<td></td>
<td></td>
</tr>
@@ -254,32 +283,33 @@ function wgerCustomModalInit()
</tr>
<tr>
<td>{% translate "Fibres" %}</td>
<td class="align-right">{{nutritional_data.total.fibres|floatformat}} {% trans_weight_unit 'g' owner_user %}</td>
<td class="align-right">{{ nutritional_data.total.fibres|floatformat }} {% trans_weight_unit 'g' owner_user %}</td>
<td></td>
<td></td>
</tr>
<tr>
<td>{% translate "Sodium" %}</td>
<td class="align-right">{{nutritional_data.total.sodium|floatformat}} {% trans_weight_unit 'g' owner_user %}</td>
<td class="align-right">{{ nutritional_data.total.sodium|floatformat }} {% trans_weight_unit 'g' owner_user %}</td>
<td></td>
<td></td>
</tr>
</tbody>
</table>
</tbody>
</table>
<h4>{% translate "Nutrition diary" %} - {{nutritional_data.total.energy|floatformat:0}}{% translate "kcal" %}</h4>
<div id="nutrition_diary_chart"></div>
<h4>{% translate "Nutrition diary" %} -
{{ nutritional_data.total.energy|floatformat:0 }}{% translate "kcal" %}</h4>
<div id="nutrition_diary_chart"></div>
<table class="table table-condensed">
<thead>
<table class="table table-condensed">
<thead>
<tr>
<th>{% translate "Date" %}</th>
<th class="align-right">{% translate "Logged" %}</th>
<th class="align-right">{% translate "Difference" %}</th>
</tr>
</thead>
<tbody>
</thead>
<tbody>
{% for entry in log_data %}
<tr>
<td>
@@ -295,7 +325,7 @@ function wgerCustomModalInit()
</td>
</tr>
{% empty %}
<tr>
<tr>
<td colspan="4">
<em>{% translate "nothing found" %}</em>
</td>
@@ -304,18 +334,20 @@ function wgerCustomModalInit()
{% if log_data %}
<tr>
<td colspan="4">
<a href="{% url 'nutrition:log:overview' plan.pk %}" class="btn btn-link btn-block">{% translate "View complete nutrition log" %}</a>
<a href="{% url 'nutrition:log:overview' plan.pk %}"
class="btn btn-link btn-block">{% translate "View complete nutrition log" %}</a>
</td>
</tr>
{% endif %}
</tbody>
</table>
</tbody>
</table>
{% if is_owner %}
<p>
<a href="{% url 'nutrition:log:add' plan.pk %}" class="btn btn-success btn-sm wger-modal-dialog">{% translate "Add custom diary entry" %}</a>
</p>
{% endif %}
{% if is_owner %}
<p>
<a href="{% url 'nutrition:log:add' plan.pk %}"
class="btn btn-success btn-sm wger-modal-dialog">{% translate "Add custom diary entry" %}</a>
</p>
{% endif %}
{% endblock %}
@@ -323,42 +355,45 @@ function wgerCustomModalInit()
{# Side bar #}
{# #}
{% block sidebar %}
<h4>{% translate "Energy" %}</h4>
<table class="table table-sm" id="nutritional-data-energy">
<thead>
<h4>{% translate "Energy" %}</h4>
<table class="table table-sm" id="nutritional-data-energy">
<thead>
<tr>
<th>{% translate "Energy" %}</th>
<th class="align-right">{{nutritional_data.total.energy|floatformat:0}} {% translate "kcal" %}</th>
<th class="align-right">{{ nutritional_data.total.energy|floatformat:0 }} {% translate "kcal" %}</th>
</tr>
</thead>
<tbody>
</thead>
<tbody>
{% if is_owner and owner_user.userprofile.calories and plan.has_goal_calories %}
{% with total=plan.get_calories_approximation %}
<tr class="table-{% if total == 1 %}default{% elif total == 2 %}success{% elif total == 3 %}warning{% elif total > 3 %}danger{% endif %}">
<td>{% translate "Goal" %}</td>
<td class="align-right">
<strong>{{owner_user.userprofile.calories}} {% translate "kcal" %}</strong></td>
</tr>
{% endwith %}
{% with total=plan.get_calories_approximation %}
<tr class="table-{% if total == 1 %}default{% elif total == 2 %}success{% elif total == 3 %}warning{% elif total > 3 %}danger{% endif %}">
<td>{% translate "Goal" %}</td>
<td class="align-right">
<strong>{{ owner_user.userprofile.calories }} {% translate "kcal" %}</strong>
</td>
</tr>
{% endwith %}
{% endif %}
</tbody>
</table>
</tbody>
</table>
{% if is_owner and plan.has_goal_calories %}
<p>{% blocktranslate %}You have selected that this nutritional plan has a
goal amount of calories. Use the calculator or enter the value yourself.{% endblocktranslate %}
<a href="{% url 'nutrition:calories:view' %}">{% translate "That's done here" %}</a>
</p>
{% endif %}
{% if is_owner and plan.has_goal_calories %}
<p>{% blocktranslate %}You have selected that this nutritional plan has a
goal amount of calories. Use the calculator or enter the value
yourself.{% endblocktranslate %}
<a href="{% url 'nutrition:calories:view' %}">{% translate "That's done here" %}</a>
</p>
{% endif %}
{% if language.short_name != 'en' and is_owner %}
<p>
{% translate "If you find the ingredient list too short, you might want to activate the preference to also show English ingredients." %}
<a href="{% url 'core:user:preferences' %}" id="ajax-english-ingredients">{% translate "That's done here" %}</a>.
</p>
{% endif %}
{% if language.short_name != 'en' and is_owner %}
<p>
{% translate "If you find the ingredient list too short, you might want to activate the preference to also show English ingredients." %}
<a href="{% url 'core:user:preferences' %}"
id="ajax-english-ingredients">{% translate "That's done here" %}</a>.
</p>
{% endif %}
{% endblock %}
@@ -367,31 +402,35 @@ function wgerCustomModalInit()
{# Options #}
{# #}
{% block options %}
<div class="btn-group">
<button type="button" class="btn btn-primary btn-sm dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
<span class="{% fa_class 'cog' %}"></span>
{% translate "Options" %}
</button>
<div class="dropdown-menu">
<a href="{% url 'nutrition:plan:export-pdf' plan.id uid token %}" target="_blank" class="dropdown-item">
<span class="{% fa_class 'download' %}"></span>
{% translate "Download as PDF" %}
</a>
{% if is_owner %}
<a href="{% url 'nutrition:plan:edit' plan.id %}" class="wger-modal-dialog dropdown-item">
<span class="{% fa_class 'edit' %}"></span>
{% translate "Edit nutrition plan" %}
<div class="btn-group">
<button type="button" class="btn btn-primary btn-sm dropdown-toggle" data-toggle="dropdown"
aria-haspopup="true" aria-expanded="false">
<span class="{% fa_class 'cog' %}"></span>
{% translate "Options" %}
</button>
<div class="dropdown-menu">
<a href="{% url 'nutrition:plan:export-pdf' plan.id uid token %}" target="_blank"
class="dropdown-item">
<span class="{% fa_class 'download' %}"></span>
{% translate "Download as PDF" %}
</a>
<a href="{% url 'nutrition:plan:copy' plan.id %}" class="dropdown-item">
<span class="{% fa_class 'clone' %}"></span>
{% translate "Make a copy of this nutrition plan" %}
</a>
<div role="separator" class="divider"></div>
<a href="{% url 'nutrition:plan:delete' plan.id %}" class="wger-modal-dialog dropdown-item">
<span class="{% fa_class 'trash' %}"></span>
{% translate "Delete nutrition plan" %}
</a>
{% endif %}
{% if is_owner %}
<a href="{% url 'nutrition:plan:edit' plan.id %}"
class="wger-modal-dialog dropdown-item">
<span class="{% fa_class 'edit' %}"></span>
{% translate "Edit nutrition plan" %}
</a>
<a href="{% url 'nutrition:plan:copy' plan.id %}" class="dropdown-item">
<span class="{% fa_class 'clone' %}"></span>
{% translate "Make a copy of this nutrition plan" %}
</a>
<div role="separator" class="divider"></div>
<a href="{% url 'nutrition:plan:delete' plan.id %}"
class="wger-modal-dialog dropdown-item">
<span class="{% fa_class 'trash' %}"></span>
{% translate "Delete nutrition plan" %}
</a>
{% endif %}
</div>
</div>
</div>
{% endblock %}