next steps in training plan/target
- delete cycles - change user
This commit is contained in:
@@ -992,7 +992,7 @@ class TrainingPlan(models.Model):
|
|||||||
firstname = self.rower.user.first_name
|
firstname = self.rower.user.first_name
|
||||||
lastname = self.rower.user.last_name
|
lastname = self.rower.user.last_name
|
||||||
|
|
||||||
stri = u'Training Plan for {firstname} {lastname} {s} - {e}: {n}'.format(
|
stri = u'Training Plan for {firstname} {lastname} {s} - {e}: {name}'.format(
|
||||||
s = startdate.strftime('%Y-%m-%d'),
|
s = startdate.strftime('%Y-%m-%d'),
|
||||||
e = enddate.strftime('%Y-%m-%d'),
|
e = enddate.strftime('%Y-%m-%d'),
|
||||||
firstname = firstname,
|
firstname = firstname,
|
||||||
|
|||||||
@@ -18,7 +18,18 @@
|
|||||||
<div class="grid_12">
|
<div class="grid_12">
|
||||||
<div class="grid_12 alpha">
|
<div class="grid_12 alpha">
|
||||||
<h1>Training Plan - {{ plan.name }}</h1>
|
<h1>Training Plan - {{ plan.name }}</h1>
|
||||||
<p><a href="/rowers/editplan/{{ plan.id }}">Edit</a></p>
|
<p>This plan starts on {{ plan.startdate }} and ends on {{ plan.enddate }}. The training plan target is: {{ plan.target.name }} on {{ plan.target.date }}.</p>
|
||||||
|
<p><a href="/rowers/editplan/{{ plan.id }}">Edit the plan</a></p>
|
||||||
|
<p>Click on the plan cycles below to edit their names, start and end dates. The gray "filler"
|
||||||
|
cycles are generated, adjusted and deleted automatically to ensure the entire plan
|
||||||
|
duration is covered with non-overlapping cycles.
|
||||||
|
Once you edit a filler cycle, it become a user-defined cycle, which cannot be deleted
|
||||||
|
by the system.</p>
|
||||||
|
<p>A good way to organize the plan is to think of micro cycles as training weeks. Macro cycles
|
||||||
|
are typically used to address specific phases of preparation and to indicate the racing
|
||||||
|
season and may span several months.
|
||||||
|
Meso cycles can be used to group sequences of three to five light, medium and
|
||||||
|
hard weeks. </p>
|
||||||
</div>
|
</div>
|
||||||
<div class="grid_4 alpha">
|
<div class="grid_4 alpha">
|
||||||
<h2>Macro Cycles</h2>
|
<h2>Macro Cycles</h2>
|
||||||
@@ -33,26 +44,45 @@
|
|||||||
<div class="grid_12 alpha">
|
<div class="grid_12 alpha">
|
||||||
{% for key,macrocycle in cycles.items %}
|
{% for key,macrocycle in cycles.items %}
|
||||||
<div class="grid_12 alpha">
|
<div class="grid_12 alpha">
|
||||||
<div class="grid_4 palegreen alpha">
|
{% if macrocycle.0.type == 'filler' %}
|
||||||
|
<div class="grid_4 filler alpha">
|
||||||
|
{% else %}
|
||||||
|
<div class="grid_4 palegreen alpha">
|
||||||
|
{% endif %}
|
||||||
<div class="padded">
|
<div class="padded">
|
||||||
<h3>{{ macrocycle.0.name }} ({{ macrocycle.0.startdate }} - {{ macrocycle.0.enddate }})</h3>
|
<h3>{{ macrocycle.0.name }} ({{ macrocycle.0.startdate }} - {{ macrocycle.0.enddate }})</h3>
|
||||||
<p><a href="/rowers/macrocycle/{{ macrocycle.0.id }}">edit</a></p>
|
<p><a href="/rowers/macrocycle/{{ macrocycle.0.id }}">edit</a>
|
||||||
|
/
|
||||||
|
<a href="/rowers/deletemacrocycle/{{ macrocycle.0.id }}">delete</a></p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="grid_8 alpha">
|
<div class="grid_8 alpha">
|
||||||
{% for key, mesocycle in macrocycle.1.items %}
|
{% for key, mesocycle in macrocycle.1.items %}
|
||||||
|
{% if mesocycle.0.type == 'filler' %}
|
||||||
|
<div class="grid_4 filler alpha">
|
||||||
|
{% else %}
|
||||||
<div class="grid_4 lightsalmon alpha">
|
<div class="grid_4 lightsalmon alpha">
|
||||||
|
{% endif %}
|
||||||
<div class="padded">
|
<div class="padded">
|
||||||
<h3>{{ mesocycle.0.name }} ({{ mesocycle.0.startdate }} - {{ mesocycle.0.enddate }})</h3>
|
<h3>{{ mesocycle.0.name }} ({{ mesocycle.0.startdate }} - {{ mesocycle.0.enddate }})</h3>
|
||||||
<p><a href="/rowers/mesocycle/{{ mesocycle.0.id }}">edit</a></p>
|
<p><a href="/rowers/mesocycle/{{ mesocycle.0.id }}">edit</a>
|
||||||
|
/
|
||||||
|
<a href="/rowers/deletemesocycle/{{ mesocycle.0.id }}">delete</a></p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="grid_4 omega">
|
<div class="grid_4 omega">
|
||||||
{% for microcycle in mesocycle.1 %}
|
{% for microcycle in mesocycle.1 %}
|
||||||
<div class="grid_4 paleblue ">
|
{% if microcycle.type == 'filler' %}
|
||||||
|
<div class="grid_4 filler">
|
||||||
|
{% else %}
|
||||||
|
<div class="grid_4 paleblue ">
|
||||||
|
{% endif %}
|
||||||
<div class="padded">
|
<div class="padded">
|
||||||
<h3>{{ microcycle.name }} ({{ microcycle.startdate }} - {{ microcycle.enddate }})</h3>
|
<h3>{{ microcycle.name }} ({{ microcycle.startdate }} - {{ microcycle.enddate }})</h3>
|
||||||
<p><a href="/rowers/microcycle/{{ microcycle.id }}">edit</a></p>
|
<p>
|
||||||
|
<a href="/rowers/microcycle/{{ microcycle.id }}">edit</a>
|
||||||
|
/
|
||||||
|
<a href="/rowers/deletemicrocycle/{{ microcycle.id }}">delete</a></p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
|||||||
@@ -15,7 +15,23 @@
|
|||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<div class="grid_12">
|
<div class="grid_12 alpha">
|
||||||
|
{% if user.is_authenticated and user|is_manager %}
|
||||||
|
<div class="grid_2 prefix_8 dropdown">
|
||||||
|
<button class="grid_2 alpha button green small dropbtn">
|
||||||
|
{{ rower.user.first_name }} {{ rower.user.last_name }}
|
||||||
|
</button>
|
||||||
|
<div class="dropdown-content">
|
||||||
|
{% for member in user|team_members %}
|
||||||
|
<a class="button green small" href="/rowers/createplan/{{ member.id }}">{{ member.first_name }} {{ member.last_name }}</a>
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<div class="grid_12 alpha">
|
||||||
<div id="targets_table" class="grid_8 alpha">
|
<div id="targets_table" class="grid_8 alpha">
|
||||||
<h1>Training Targets</h1>
|
<h1>Training Targets</h1>
|
||||||
|
|
||||||
@@ -64,8 +80,8 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
<div class="grid_12">
|
<div class="grid_12 alpha">
|
||||||
|
|
||||||
<div id="courses_table" class="grid_8 alpha">
|
<div id="courses_table" class="grid_8 alpha">
|
||||||
<h1>Plans</h1>
|
<h1>Plans</h1>
|
||||||
|
|
||||||
|
|||||||
30
rowers/templates/trainingplan_delete.html
Normal file
30
rowers/templates/trainingplan_delete.html
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
{% extends "base.html" %}
|
||||||
|
{% load staticfiles %}
|
||||||
|
{% load rowerfilters %}
|
||||||
|
|
||||||
|
{% block title %}Rowsandall Training Plans{% endblock %}
|
||||||
|
|
||||||
|
{% block scripts %}
|
||||||
|
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<style>
|
||||||
|
#mypointer {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<div class="grid_12 alpha">
|
||||||
|
|
||||||
|
<form action="" method="post">
|
||||||
|
{% csrf_token %}
|
||||||
|
<p>Are you sure you want to delete <i>{{ object }}</i>?</p>
|
||||||
|
<div id="formbutton" class="grid_1 prefix_2">
|
||||||
|
<input class="button red" type="submit" value="Confirm">
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
{% endblock %}
|
||||||
@@ -420,8 +420,12 @@ urlpatterns = [
|
|||||||
url(r'^workout/compare/(?P<id1>\d+)/(?P<id2>\d+)/(?P<xparam>\w+.*)/(?P<yparam>[\w\ ]+.*)/$',views.workout_comparison_view2),
|
url(r'^workout/compare/(?P<id1>\d+)/(?P<id2>\d+)/(?P<xparam>\w+.*)/(?P<yparam>[\w\ ]+.*)/$',views.workout_comparison_view2),
|
||||||
url(r'^test\_callback',views.rower_process_testcallback),
|
url(r'^test\_callback',views.rower_process_testcallback),
|
||||||
url(r'^createplan$',views.rower_create_trainingplan),
|
url(r'^createplan$',views.rower_create_trainingplan),
|
||||||
url(r'^createplan/(?P<id>\d+)$',views.rower_create_trainingplan),
|
url(r'^createplan/(?P<userid>\d+)$',views.rower_create_trainingplan),
|
||||||
url(r'^deleteplan/(?P<id>\d+)$',views.rower_delete_trainingplan),
|
url(r'^deleteplan/(?P<pk>\d+)$',views.TrainingPlanDelete.as_view()),
|
||||||
|
url(r'^deletemicrocycle/(?P<pk>\d+)$',views.MicroCycleDelete.as_view()),
|
||||||
|
url(r'^deletemesocycle/(?P<pk>\d+)$',views.MesoCycleDelete.as_view()),
|
||||||
|
url(r'^deletemacrocycle/(?P<pk>\d+)$',views.MacroCycleDelete.as_view()),
|
||||||
|
# url(r'^deleteplan/(?P<id>\d+)$',views.rower_delete_trainingplan),
|
||||||
url(r'^plan/(?P<id>\d+)$',views.rower_trainingplan_view),
|
url(r'^plan/(?P<id>\d+)$',views.rower_trainingplan_view),
|
||||||
url(r'^macrocycle/(?P<pk>\d+)$',views.TrainingMacroCycleUpdate.as_view()),
|
url(r'^macrocycle/(?P<pk>\d+)$',views.TrainingMacroCycleUpdate.as_view()),
|
||||||
url(r'^mesocycle/(?P<pk>\d+)$',views.TrainingMesoCycleUpdate.as_view()),
|
url(r'^mesocycle/(?P<pk>\d+)$',views.TrainingMesoCycleUpdate.as_view()),
|
||||||
|
|||||||
159
rowers/views.py
159
rowers/views.py
@@ -28,7 +28,7 @@ import isodate
|
|||||||
|
|
||||||
from django.shortcuts import render
|
from django.shortcuts import render
|
||||||
|
|
||||||
from django.views.generic.edit import UpdateView
|
from django.views.generic.edit import UpdateView,DeleteView
|
||||||
|
|
||||||
from django.http import (
|
from django.http import (
|
||||||
HttpResponse, HttpResponseRedirect,
|
HttpResponse, HttpResponseRedirect,
|
||||||
@@ -45,7 +45,8 @@ from rowers.forms import (
|
|||||||
VirtualRaceSelectForm,WorkoutRaceSelectForm,CourseSelectForm,
|
VirtualRaceSelectForm,WorkoutRaceSelectForm,CourseSelectForm,
|
||||||
RaceResultFilterForm,PowerIntervalUpdateForm
|
RaceResultFilterForm,PowerIntervalUpdateForm
|
||||||
)
|
)
|
||||||
from django.core.urlresolvers import reverse
|
from django.core.urlresolvers import reverse, reverse_lazy
|
||||||
|
|
||||||
from django.core.exceptions import PermissionDenied
|
from django.core.exceptions import PermissionDenied
|
||||||
from django.template import RequestContext
|
from django.template import RequestContext
|
||||||
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
|
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
|
||||||
@@ -207,6 +208,7 @@ class JSONResponse(HttpResponse):
|
|||||||
|
|
||||||
def getrequestrower(request,rowerid=0,userid=0,notpermanent=False):
|
def getrequestrower(request,rowerid=0,userid=0,notpermanent=False):
|
||||||
|
|
||||||
|
|
||||||
if notpermanent == False:
|
if notpermanent == False:
|
||||||
if rowerid == 0 and 'rowerid' in request.session:
|
if rowerid == 0 and 'rowerid' in request.session:
|
||||||
rowerid = request.session['rowerid']
|
rowerid = request.session['rowerid']
|
||||||
@@ -14181,47 +14183,11 @@ def virtualevent_submit_result_view(request,id=0):
|
|||||||
})
|
})
|
||||||
|
|
||||||
@user_passes_test(hasplannedsessions,login_url="/", redirect_field_name=None)
|
@user_passes_test(hasplannedsessions,login_url="/", redirect_field_name=None)
|
||||||
def rower_delete_trainingtarget(request,id=0):
|
def rower_create_trainingplan(request,userid=0):
|
||||||
try:
|
|
||||||
target = TrainingTarget.objects.get(id=id)
|
|
||||||
except TrainingPlan.DoesNotExist:
|
|
||||||
raise Http404("Training Plan Does Not Exist")
|
|
||||||
|
|
||||||
if checkaccessuser(request.user,target.rower):
|
|
||||||
target.delete()
|
|
||||||
messages.info(request,"We have deleted the training plan")
|
|
||||||
else:
|
|
||||||
raise PermissionDenied("Access denied")
|
|
||||||
|
|
||||||
url = reverse(rower_create_trainingplan)
|
therower = getrequestrower(request,userid=userid)
|
||||||
|
|
||||||
return HttpResponseRedirect(url)
|
|
||||||
|
|
||||||
|
|
||||||
@user_passes_test(hasplannedsessions,login_url="/", redirect_field_name=None)
|
|
||||||
def rower_delete_trainingplan(request,id=0):
|
|
||||||
try:
|
|
||||||
plan = TrainingPlan.objects.get(id=id)
|
|
||||||
except TrainingPlan.DoesNotExist:
|
|
||||||
raise Http404("Training Plan Does Not Exist")
|
|
||||||
|
|
||||||
if checkaccessuser(request.user,plan.rower):
|
|
||||||
plan.delete()
|
|
||||||
messages.info(request,"We have deleted the training plan")
|
|
||||||
else:
|
|
||||||
raise PermissionDenied("Access denied")
|
|
||||||
|
|
||||||
url = reverse(rower_create_trainingplan)
|
|
||||||
|
|
||||||
return HttpResponseRedirect(url)
|
|
||||||
|
|
||||||
@user_passes_test(hasplannedsessions,login_url="/", redirect_field_name=None)
|
|
||||||
def rower_create_trainingplan(request,id=0):
|
|
||||||
|
|
||||||
therower = getrequestrower(request,userid=id)
|
|
||||||
theuser = therower.user
|
theuser = therower.user
|
||||||
|
|
||||||
|
|
||||||
if request.method == 'POST' and 'date' in request.POST:
|
if request.method == 'POST' and 'date' in request.POST:
|
||||||
targetform = TrainingTargetForm(request.POST)
|
targetform = TrainingTargetForm(request.POST)
|
||||||
if targetform.is_valid():
|
if targetform.is_valid():
|
||||||
@@ -14266,10 +14232,119 @@ def rower_create_trainingplan(request,id=0):
|
|||||||
return render(request,'trainingplan_create.html',
|
return render(request,'trainingplan_create.html',
|
||||||
{
|
{
|
||||||
'form':form,
|
'form':form,
|
||||||
|
'rower':therower,
|
||||||
'plans':plans,
|
'plans':plans,
|
||||||
'targets':targets,
|
'targets':targets,
|
||||||
'targetform':targetform,
|
'targetform':targetform,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@user_passes_test(hasplannedsessions,login_url="/", redirect_field_name=None)
|
||||||
|
def rower_delete_trainingtarget(request,id=0):
|
||||||
|
try:
|
||||||
|
target = TrainingTarget.objects.get(id=id)
|
||||||
|
except TrainingPlan.DoesNotExist:
|
||||||
|
raise Http404("Training Plan Does Not Exist")
|
||||||
|
|
||||||
|
if checkaccessuser(request.user,target.rower):
|
||||||
|
target.delete()
|
||||||
|
messages.info(request,"We have deleted the training plan")
|
||||||
|
else:
|
||||||
|
raise PermissionDenied("Access denied")
|
||||||
|
|
||||||
|
url = reverse(rower_create_trainingplan)
|
||||||
|
|
||||||
|
return HttpResponseRedirect(url)
|
||||||
|
|
||||||
|
|
||||||
|
@user_passes_test(hasplannedsessions,login_url="/", redirect_field_name=None)
|
||||||
|
def rower_delete_trainingplan(request,id=0):
|
||||||
|
try:
|
||||||
|
plan = TrainingPlan.objects.get(id=id)
|
||||||
|
except TrainingPlan.DoesNotExist:
|
||||||
|
raise Http404("Training Plan Does Not Exist")
|
||||||
|
|
||||||
|
if checkaccessuser(request.user,plan.rower):
|
||||||
|
plan.delete()
|
||||||
|
messages.info(request,"We have deleted the training plan")
|
||||||
|
else:
|
||||||
|
raise PermissionDenied("Access denied")
|
||||||
|
|
||||||
|
url = reverse(rower_create_trainingplan)
|
||||||
|
|
||||||
|
return HttpResponseRedirect(url)
|
||||||
|
|
||||||
|
class TrainingPlanDelete(DeleteView):
|
||||||
|
model = TrainingPlan
|
||||||
|
template_name = 'trainingplan_delete.html'
|
||||||
|
success_url = reverse_lazy(rower_create_trainingplan)
|
||||||
|
|
||||||
|
def get_object(self, *args, **kwargs):
|
||||||
|
obj = super(TrainingPlanDelete, self).get_object(*args, **kwargs)
|
||||||
|
if not checkaccessuser(self.request.user,obj.plan.rower):
|
||||||
|
raise Http404
|
||||||
|
|
||||||
|
return obj
|
||||||
|
|
||||||
|
class MicroCycleDelete(DeleteView):
|
||||||
|
model = TrainingMicroCycle
|
||||||
|
template_name = 'trainingplan_delete.html'
|
||||||
|
|
||||||
|
def get_success_url(self):
|
||||||
|
plan = self.object.plan.plan.plan
|
||||||
|
createmacrofillers(plan)
|
||||||
|
return reverse(rower_trainingplan_view,
|
||||||
|
kwargs = {
|
||||||
|
'id':plan.id
|
||||||
|
})
|
||||||
|
|
||||||
|
def get_object(self, *args, **kwargs):
|
||||||
|
obj = super(MicroCycleDelete, self).get_object(*args, **kwargs)
|
||||||
|
if not checkaccessuser(self.request.user,obj.plan.plan.plan.rower):
|
||||||
|
raise Http404
|
||||||
|
|
||||||
|
return obj
|
||||||
|
|
||||||
|
|
||||||
|
class MesoCycleDelete(DeleteView):
|
||||||
|
model = TrainingMesoCycle
|
||||||
|
template_name = 'trainingplan_delete.html'
|
||||||
|
|
||||||
|
def get_success_url(self):
|
||||||
|
plan = self.object.plan.plan
|
||||||
|
createmacrofillers(plan)
|
||||||
|
return reverse(rower_trainingplan_view,
|
||||||
|
kwargs = {
|
||||||
|
'id':plan.id
|
||||||
|
})
|
||||||
|
|
||||||
|
def get_object(self, *args, **kwargs):
|
||||||
|
obj = super(MesoCycleDelete, self).get_object(*args, **kwargs)
|
||||||
|
if not checkaccessuser(self.request.user,obj.plan.plan.rower):
|
||||||
|
raise Http404
|
||||||
|
|
||||||
|
return obj
|
||||||
|
|
||||||
|
|
||||||
|
class MacroCycleDelete(DeleteView):
|
||||||
|
model = TrainingMacroCycle
|
||||||
|
template_name = 'trainingplan_delete.html'
|
||||||
|
|
||||||
|
def get_success_url(self):
|
||||||
|
plan = self.object.plan
|
||||||
|
createmacrofillers(plan)
|
||||||
|
return reverse(rower_trainingplan_view,
|
||||||
|
kwargs = {
|
||||||
|
'id':plan.id
|
||||||
|
})
|
||||||
|
|
||||||
|
def get_object(self, *args, **kwargs):
|
||||||
|
obj = super(MacroCycleDelete, self).get_object(*args, **kwargs)
|
||||||
|
if not checkaccessuser(self.request.user,obj.plan.rower):
|
||||||
|
raise Http404
|
||||||
|
|
||||||
|
return obj
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@user_passes_test(hasplannedsessions,login_url="/", redirect_field_name=None)
|
@user_passes_test(hasplannedsessions,login_url="/", redirect_field_name=None)
|
||||||
@@ -14371,6 +14446,8 @@ class TrainingMesoCycleUpdate(UpdateView):
|
|||||||
else:
|
else:
|
||||||
obj.type = 'userdefined'
|
obj.type = 'userdefined'
|
||||||
obj.save()
|
obj.save()
|
||||||
|
obj.plan.type = 'userdefined'
|
||||||
|
obj.plan.save()
|
||||||
return obj
|
return obj
|
||||||
|
|
||||||
class TrainingMicroCycleUpdate(UpdateView):
|
class TrainingMicroCycleUpdate(UpdateView):
|
||||||
@@ -14401,6 +14478,8 @@ class TrainingMicroCycleUpdate(UpdateView):
|
|||||||
else:
|
else:
|
||||||
obj.type = 'userdefined'
|
obj.type = 'userdefined'
|
||||||
obj.save()
|
obj.save()
|
||||||
|
obj.plan.type = 'userdefined'
|
||||||
|
obj.plan.save()
|
||||||
return obj
|
return obj
|
||||||
|
|
||||||
class TrainingPlanUpdate(UpdateView):
|
class TrainingPlanUpdate(UpdateView):
|
||||||
|
|||||||
@@ -516,6 +516,14 @@ a.button {
|
|||||||
box-shadow:inset 0px 0px 0px 6px #fff;
|
box-shadow:inset 0px 0px 0px 6px #fff;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* filler */
|
||||||
|
.filler {
|
||||||
|
background: darkgray;
|
||||||
|
box-shadow:inset 0px 0px 0px 6px #fff;
|
||||||
|
-moz-box-shadow:inset 0px 0px 0px 6px #fff;
|
||||||
|
box-shadow:inset 0px 0px 0px 6px #fff;
|
||||||
|
}
|
||||||
|
|
||||||
.padded {
|
.padded {
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user