Private
Public Access
1
0

adding template edit functionality

This commit is contained in:
Sander Roosendaal
2020-02-01 15:25:52 +01:00
parent 170fb3c8b6
commit aca8f28457
8 changed files with 346 additions and 12 deletions

View File

@@ -2342,6 +2342,35 @@ class PlannedSessionForm(ModelForm):
self.fields['sessiontype'].choices = regularsessiontypechoices
class PlannedSessionTemplateForm(ModelForm):
class Meta:
model = PlannedSession
fields = [
'name',
'sessiontype',
'sessionmode',
'criterium',
'sessionvalue',
'sessionunit',
'course',
'comment',
]
dateTimeOptions = {
'format': 'yyyy-mm-dd',
'autoclose': True,
}
widgets = {
'comment': forms.Textarea,
}
def __init__(self,*args,**kwargs):
super(PlannedSessionTemplateForm, self).__init__(*args, **kwargs)
self.fields['course'].queryset = GeoCourse.objects.all().order_by("country","name")
self.fields['sessiontype'].choices = regularsessiontypechoices
def get_course_timezone(course):
polygons = GeoPolygon.objects.filter(course = course)
points = GeoPoint.objects.filter(polygon = polygons[0])

View File

@@ -108,6 +108,7 @@
<th>Name</th>
<th>Value</th>
<th>&nbsp;</th>
<th>Edit</th>
<th>Delete</th>
</tr>
</thead>
@@ -125,6 +126,9 @@
</td>
<td> {{ ps.sessionvalue }} </td>
<td> {{ ps.sessionunit }} </td>
<td>
<a class="small" href="/rowers/sessions/{{ ps.id }}/templateedit/">Edit Template</a>
</td>
<td>
<a class="small" href="/rowers/sessions/{{ ps.id }}/deleteconfirm/">Delete</a>
</td>

View File

@@ -115,6 +115,7 @@
<th>Name</th>
<th>Value</th>
<th>&nbsp;</th>
<th>Edit</th>
<th>Delete</th>
</tr>
</thead>
@@ -132,6 +133,9 @@
</td>
<td> {{ ps.sessionvalue }} </td>
<td> {{ ps.sessionunit }} </td>
<td>
<a class="small" href="/rowers/sessions/{{ ps.id }}/templateedit/">Edit Template</a>
</td>
<td>
<a class="small" href="/rowers/sessions/{{ ps.id }}/deleteconfirm/">Delete</a>
</td>

View File

@@ -0,0 +1,197 @@
{% extends "newbase.html" %}
{% load staticfiles %}
{% load rowerfilters %}
{% block title %}Update Template Session{% endblock %}
{% block main %}
<h1>Edit Session Template</h1>
<ul class="main-content">
<li class="grid_2">
<h2>{{ thesession.name }}</h2>
<form enctype="multipart/form-data" action="{{ formloc }}" method="post">
{% if form.errors %}
<p style="color: red;">
Please correct the error{{ form.errors|pluralize }} below.
</p>
{% endif %}
<p>
<table>
{{ form.as_table }}
</table>
</p>
{% csrf_token %}
<div id="id_guidance">
</div>
<p>
<a href="/rowers/sessions/{{ thesession.id }}/deleteconfirm">Delete</a>
</p>
<input class="button"
action="/rowers/sessions/{{ thesession.id }}/templateedit/" type="submit" value="Save">
</form>
</li>
<li class="grid_2">
<h1>Templates</h1>
<p>
Click on session name to clone to current period
</p>
<table class="listtable shortpadded" width="80%">
<thead>
<tr>
<th>Name</th>
<th>Value</th>
<th>&nbsp;</th>
<th>Edit</th>
<th>Delete</th>
</tr>
</thead>
<tbody>
{% for ps in sessiontemplates %}
<tr>
<td>
{% if ps.name != '' %}
<a class="small"
href="/rowers/sessions/{{ ps.id }}/clone/user/{{ rower.user.id }}/?when={{ timeperiod }}">{{ ps.name }}</a>
{% else %}
<a class="small"
href="/rowers/sessions/{{ ps.id }}/clone/user/{{ rower.user.id }}/?when={{ timeperiod }}">Unnamed Session</a>
{% endif %}
</td>
<td> {{ ps.sessionvalue }} </td>
<td> {{ ps.sessionunit }} </td>
<td>
<a class="small" href="/rowers/sessions/{{ ps.id }}/templateedit/">Edit Template</a>
</td>
<td>
<a class="small" href="/rowers/sessions/{{ ps.id }}/deleteconfirm/">Delete</a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</li>
</ul>
{% endblock %}
{% block sidebar %}
{% include 'menu_plan.html' %}
{% endblock %}
{% block scripts %}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>
<script>
$(document).ready(function(){
var o = $("td #id_sessiontype").find(":selected").val();
if (o != 'coursetest') {
$("td #id_course").hide();
$("th label[for='id_course']").hide();
} else {
$("td #id_course").show();
$("th label[for='id_course']").show();
}
$("td #id_sessionmode").change(function() {
if (this.value == 'TRIMP') {
$("td #id_sessionunit").prop("value","None");
$('#id_guidance').html("<p>TRIMP has no unit</p>");
}
if (this.value == 'distance') {
$("td #id_sessionunit").prop("value","m");
$('#id_guidance').html("<p>Distance: Set value to meters</p>");
}
if (this.value == 'time') {
$("td #id_sessionunit").prop("value","min");
$('#id_guidance').html("<p>Time: Set value to minutes</p>");
}
if (this.value == 'rScore') {
$("td #id_sessionunit").prop("value","None");
$('#id_guidance').html("<p>rScore has no unit</p>");
}
});
$("td #id_sessiontype").change(function() {
if (this.value == 'session') {
$("td #id_criterium").prop("value","none");
$('#id_guidance').html("<p>For Training Sessions, the default criterium is 'Approximately'</p>");
}
if (this.value == 'test') {
$("td #id_criterium").prop("value","exact");
$("td #id_sessionmode").prop("value","distance");
$("td #id_sessionunit").prop("value","m");
$('#id_guidance').html("<p>Set mode to distance. For Mandatory Tests, only distance or time are allowed.</p><p>For Mandatory Tests, the only criterium is 'Exactly'</p>");
}
if (this.value == 'coursetest') {
$("th label[for='id_course']").show();
$("td #id_course").show();
$("td #id_criterium").prop("value","none");
$("td #id_sessionmode").prop("value","distance");
$("td #id_sessionunit").prop("value","m");
$('#id_guidance').html("<p>Set mode to distance. For OTW Tests, only distance is allowed.</p><p>The exact value is not relevant because it is calculated from the course.</p>");
}
if (this.value != 'coursetest') {
$("th label[for='id_course']").hide();
$("td #id_course").hide();
}
if (this.value == 'challenge') {
$("td #id_criterium").prop("value","minimum");
$('#id_guidance').html("<p>For Challenges, the default criterium is 'At Least'</p>");
}
if (this.value == 'cycletarget') {
$("td #id_criterium").prop("value","none");
$('#id_guidance').html("<p>For Cycle Targets, the default criterium is 'Approximately'</p>");
}
}
);
$("td #id_sessionunit").change(function() {
if (this.value == 'm') {
$("td #id_sessionmode").prop("value","distance");
$('#id_guidance').html("<p>Mode was set to distance</p>");
}
if (this.value == 'km') {
$("td #id_sessionmode").prop("value","distance");
$('#id_guidance').html("<p>Mode was set to distance</p>");
}
if (this.value == 'None') {
$("td #id_sessionmode").prop("value","rScore");
$('#id_guidance').html("<p>Mode was set to rScore</p>");
}
if (this.value == 'min') {
$("td #id_sessionmode").prop("value","time");
$('#id_guidance').html("<p>Mode was set to time</p>");
}
}
);
});
</script>
{% endblock %}

View File

@@ -16,6 +16,8 @@
<p>
<a href="/rowers/sessions/{{ psdict.id.1 }}/edit/user/{{ rower.user.id }}">
Edit Session</a>
/
<a href="/rowers/sessions/{{ psdict.id.1 }}/maketemplate/?next={{ request.path|urlencode }}">Save to template</a>
</p>
{% endif %}
<h1>Session {{ psdict.name.1 }}</h1>
@@ -157,11 +159,11 @@
<li class="grid_2">
<h2>Course</h2>
{{ coursediv|safe }}
{{ coursescript|safe }}
</li>
{% endif %}
</ul>

View File

@@ -666,6 +666,7 @@ urlpatterns = [
views.plannedsession_multicreate_view,
name='plannedsession_multicreate_view'),
re_path(r'^sessions/(?P<id>\d+)/edit/$',views.plannedsession_edit_view),
re_path(r'^sessions/(?P<id>\d+)/templateedit/',views.plannedsession_templateedit_view),
re_path(r'^sessions/(?P<id>\d+)/maketemplate/$',views.plannedsession_totemplate_view),
re_path(r'^sessions/(?P<id>\d+)/compare/$',
views.plannedsession_compare_view,

View File

@@ -704,7 +704,9 @@ def plannedsession_teamcreate_view(request,
enddatestring = enddate.strftime('%Y-%m-%d')
url += '?when='+startdatestring+'/'+enddatestring
return HttpResponseRedirect(url)
next = request.GET.get('next', url)
return HttpResponseRedirect(next)
else:
timeperiod = startdate.strftime('%Y-%m-%d')+'/'+enddate.strftime('%Y-%m-%d')
breadcrumbs = [
@@ -897,8 +899,8 @@ def plannedsession_teamedit_view(request,
enddatestring = enddate.strftime('%Y-%m-%d')
url += '?when='+startdatestring+'/'+enddatestring
return HttpResponseRedirect(url)
next = request.GET.get('next', url)
return HttpResponseRedirect(next)
else:
sessioncreateform = PlannedSessionForm(instance=ps)
sessionteamselectform = PlannedSessionTeamForm(
@@ -1465,8 +1467,8 @@ def plannedsession_clone_view(request,id=0,userid=0):
enddatestring = enddate.strftime('%Y-%m-%d')
url += '?when='+startdatestring+'/'+enddatestring
return HttpResponseRedirect(url)
next = request.GET.get('next', url)
return HttpResponseRedirect(next)
# Clone an existing planned session
# need clarity on cloning behavior time shift
@@ -1531,8 +1533,101 @@ def plannedsession_teamclone_view(request,id=0):
enddatestring = enddate.strftime('%Y-%m-%d')
url += '?when='+startdatestring+'/'+enddatestring
next = request.GET.get('next', url)
return HttpResponseRedirect(next)
@user_passes_test(hasplannedsessions, login_url="/rowers/paidplans/",
message="This functionality requires a Coach or Self-Coach plan",
redirect_field_name=None)
def plannedsession_templateedit_view(request,id=0):
r = getrequestrower(request)
startdate,enddate = get_dates_timeperiod(request)
try:
trainingplan = TrainingPlan.objects.filter(
startdate__lte = startdate,
rowers = r,
enddate__gte = enddate)[0]
except IndexError:
trainingplan = None
try:
ps = PlannedSession.objects.get(id=id)
except PlannedSession.DoesNotExist:
raise Http404("Planned Session does not exist")
if ps.manager != request.user:
raise PermissionDenied("You are not allowed to edit this planned session")
if ps.sessiontype in ['race','indoorrace']:
raise PermissionDenied("You are not allowed to edit this planned session because it is a race")
if not ps.is_template:
ps.pk = None
ps.id = None
ps.is_template = True
ps.startdate = datetime.date(1970,1,1)
ps.enddate = datetime.date(1970,1,1)
ps.team.clear()
ps.save()
sessioncreateform = PlannedSessionTemplateForm(instance=ps)
if request.method == 'POST':
sessioncreateform = PlannedSessionTemplateForm(request.POST,instance=ps)
if sessioncreateform.is_valid():
cd = sessioncreateform.cleaned_data
if cd['sessionunit'] == 'min':
cd['sessionmode'] = 'time'
elif cd['sessionunit'] in ['km','m']:
cd['sessionmode'] = 'distance'
res, message = update_plannedsession(ps,cd)
if res:
messages.info(request,message)
else:
messages.error(request,message)
url = reverse(plannedsession_templateedit_view,
kwargs = {
'id':int(ps.id),
})
startdatestring = startdate.strftime('%Y-%m-%d')
enddatestring = enddate.strftime('%Y-%m-%d')
url += '?when='+startdatestring+'/'+enddatestring
next = request.GET.get('next', url)
return HttpResponseRedirect(next)
breadcrumbs = [
{
'url': reverse(plannedsessions_view),
'name': 'Sessions'
},
{
'url':reverse(plannedsession_templateedit_view,
kwargs={
'id':id,
}
),
'name': 'Edit'
}
]
sessiontemplates = PlannedSession.objects.filter(manager=request.user,is_template=True)
return render(request,'plannedsessiontemplateedit.html',
{
'teams':get_my_teams(request.user),
'plan': trainingplan,
'breadcrumbs': breadcrumbs,
'form': sessioncreateform,
'active':'nav-plan',
'thesession': ps,
'sessiontemplates': sessiontemplates,
'rower': r,
})
return HttpResponseRedirect(url)
@user_passes_test(hasplannedsessions, login_url="/rowers/paidplans/",
message="This functionality requires a Coach or Self-Coach plan",
@@ -1564,7 +1659,9 @@ def plannedsession_totemplate_view(request,id=0):
enddatestring = enddate.strftime('%Y-%m-%d')
url += '?when='+startdatestring+'/'+enddatestring
return HttpResponseRedirect(url)
next = request.GET.get('next', url)
return HttpResponseRedirect(next)
# Edit an existing planned session
@user_passes_test(hasplannedsessions,login_url="/rowers/paidplans/",
@@ -1715,8 +1812,8 @@ def plannedsession_detach_view(request,id=0,psid=0):
remove_workout_plannedsession(w,ps)
url = reverse(plannedsession_view,kwargs={'id':psid})
return HttpResponseRedirect(url)
next = request.GET.get('next', url)
return HttpResponseRedirect(next)
@login_required()
def plannedsession_view(request,id=0,userid=0):

View File

@@ -107,7 +107,7 @@ from rowers.models import (
WorkoutComment,WorkoutCommentForm,RowerExportForm,
CalcAgePerformance,
PowerTimeFitnessMetric,BlogPost,
PlannedSessionForm,
PlannedSessionForm,PlannedSessionTemplateForm,
PlannedSessionFormSmall,GeoCourseEditForm,VirtualRace,
VirtualRaceForm,VirtualRaceResultForm,RowerImportExportForm,
IndoorVirtualRaceResultForm,IndoorVirtualRaceResult,