diff --git a/rowers/models.py b/rowers/models.py
index 06364051..ef789caa 100644
--- a/rowers/models.py
+++ b/rowers/models.py
@@ -2414,7 +2414,7 @@ class PlannedSessionStep(models.Model):
manager = models.ForeignKey(User, null=True, on_delete=models.CASCADE)
name = models.TextField(default='',max_length=200, blank=True, null=True)
type = models.TextField(default='',max_length=200, blank=True, null=True)
- durationvalue = models.IntegerField(default=0)
+ durationvalue = models.FloatField(default=0)
durationtype = models.TextField(default='',max_length=200, blank=True, null=True,
choices=durationtypes)
targetvalue = models.IntegerField(default=0)
@@ -2435,6 +2435,8 @@ class PlannedSessionStep(models.Model):
elif self.intensity == "Rest":
self.color = 'add8e6'
+ self.durationvalue = int(self.durationvalue)
+
super(PlannedSessionStep, self).save(*args, **kwargs)
def asdict(self):
@@ -2442,7 +2444,10 @@ class PlannedSessionStep(models.Model):
'wkt_step_name': self.name,
'durationType': self.durationtype,
'durationValue': self.durationvalue,
+ 'targetType': self.targettype,
'targetValue': self.targetvalue,
+ 'targetValueLow': self.targetvaluelow,
+ 'targetValueHigh': self.targetvaluehigh,
'description': self.description,
'stepId': self.pk,
'intensity': self.intensity,
@@ -2458,13 +2463,33 @@ class StepEditorForm(ModelForm):
#'type',
'durationtype',
'durationvalue',
+ 'targettype',
+ 'targetvalue',
+ 'targetvaluelow',
+ 'targetvaluehigh',
'intensity',
+ 'description',
]
widgets = {
'name': forms.Textarea(attrs={'rows':1, 'cols':50}),
}
+ def __init__(self, *args, **kwargs):
+ super(StepEditorForm, self).__init__(*args, **kwargs)
+ if self.instance.durationtype == 'Time':
+ self.initial['durationvalue'] = self.instance.durationvalue / 60000
+ elif self.instance.durationtype == 'Distance':
+ form.initial['durationvalue'] = self.instance.durationvalue / 100
+
+ def save(self, *args, **kwargs):
+ # conversions
+ if self.instance.durationtype == 'Time':
+ self.instance.durationvalue *= 60000
+ elif self.instance.durationtype == 'Distance':
+ self.instance.durationvalue *= 100
+ return super(StepEditorForm, self).save(*args, **kwargs)
+
class PlannedSession(models.Model):
diff --git a/rowers/templates/plannedsessiontemplateedit.html b/rowers/templates/plannedsessiontemplateedit.html
index d3c15a01..303d47cf 100644
--- a/rowers/templates/plannedsessiontemplateedit.html
+++ b/rowers/templates/plannedsessiontemplateedit.html
@@ -35,6 +35,15 @@
+
+ {% if steps %}
+ Steps
+ {{ steps|safe }}
+
+ Edit Steps (experimental)
+
+ {% endif %}
+
{% endblock %}
diff --git a/rowers/templates/stepedit.html b/rowers/templates/stepedit.html
new file mode 100644
index 00000000..1e6a0530
--- /dev/null
+++ b/rowers/templates/stepedit.html
@@ -0,0 +1,38 @@
+{% extends "newbase.html" %}
+{% load static %}
+{% load rowerfilters %}
+
+{% block title %}Rowsandall Training Plans{% endblock %}
+
+
+{% block main %}
+Edit {{ step.name }}
+
+ -
+
+ WARNING: This is experimental functionality which may not behave as you
+ expect. Does not work on smartphones.
+
+
+-
+
Step Description
+ {{ stepdescription }}
+
+-
+
Add new step
+
+
+
+{% endblock %}
+
+
+{% block sidebar %}
+{% include 'menu_plan.html' %}
+{% endblock %}
diff --git a/rowers/templates/stepeditor.html b/rowers/templates/stepeditor.html
index ecfee243..ec64d60d 100644
--- a/rowers/templates/stepeditor.html
+++ b/rowers/templates/stepeditor.html
@@ -19,14 +19,47 @@
Training Steps for {{ ps.name }}
+
+
+
+{% for step in currentsteps %}
+
+
+ {{ step.name }}
+
+
+
+
+
+
+
+
+
+
+
+
+{% endfor %}
Library
{% for step in steps %}
-
-
+
+
{{ step.name }}
-
+
+
+
+
+
+
+
+
+
+
+
{% endfor %}
@@ -57,18 +90,16 @@
{% endblock %}
diff --git a/rowers/urls.py b/rowers/urls.py
index 049e6bb6..49cfa865 100644
--- a/rowers/urls.py
+++ b/rowers/urls.py
@@ -875,6 +875,12 @@ urlpatterns = [
views.rower_create_trainingplan, name='rower_create_trainingplan'),
re_path(r'^plans/$', views.rower_select_instantplan,
name='rower_select_instantplan'),
+ re_path(r'^plans/step/(?P\d+)/edit/$',
+ views.stepedit, name='stepedit'),
+ re_path(r'^plans/step/(?P\d+)/edit/(?P\d+)/$',
+ views.stepedit, name='stepedit'),
+ re_path(r'^plans/step/(?P\d+)/delete/$',
+ views.stepdelete, name='stepdelete'),
re_path(r'^plans/stepeditor/$',
views.stepeditor, name='stepeditor'),
re_path(r'^plans/stepeditor/(?P\d+)/$',
diff --git a/rowers/views/planviews.py b/rowers/views/planviews.py
index 6612e01f..3012334a 100644
--- a/rowers/views/planviews.py
+++ b/rowers/views/planviews.py
@@ -2005,6 +2005,12 @@ def plannedsession_templateedit_view(request, id=0):
sessiontemplates = sessiontemplates | sessiontemplates2
+ steps = ''
+ if ps.steps: # pragma: no cover
+ d = ps.steps
+
+ steps = ps_dict_get_description_html(d, short=False)
+
return render(request, 'plannedsessiontemplateedit.html',
{
'teams': get_my_teams(request.user),
@@ -2015,6 +2021,7 @@ def plannedsession_templateedit_view(request, id=0):
'thesession': ps,
'sessiontemplates': sessiontemplates,
'rower': r,
+ 'steps': steps,
})
@@ -2975,6 +2982,8 @@ def stepadder(request, id=0):
)
ps = get_object_or_404(PlannedSession, pk=id)
+ is_save = request.GET.get('save',0)
+
if request.method != 'POST':
message = {'status': 'false',
'message': 'this view cannot be accessed through GET'}
@@ -2996,27 +3005,159 @@ def stepadder(request, id=0):
return JSONResponse(status=403, data=message)
steps = {
- "filename": "",
+ "filename": ps.steps['filename'],
+ "sport": ps.steps['sport'],
+ "steps": []
}
- for id in post_data:
+
+ for nr,id in enumerate(post_data):
try:
step = PlannedSessionStep.objects.get(id=int(id))
- print(step.name)
# add JSON
+ d = step.asdict()
+ d['stepId'] = nr
+ steps['steps'].append(d)
except PlannedSessionStep.DoesNotExist:
- print('fail')
pass
+ if is_save:
+ # save the darn thing
+ ps.steps = steps
+
+ ps.interval_string = ''
+ ps.fitfile = None
+ ps.save()
+
return JSONResponse(status=200,data=post_data)
+@user_passes_test(can_plan, login_url="/rowers/paidplans",
+ message="This functionality requires a Coach or Self-Coach plan",
+ redirect_field_name=None)
+def stepdelete(request, id=0):
+ step = get_object_or_404(PlannedSessionStep, pk=id)
+
+ step.delete()
+
+ backid = request.GET.get('id')
+
+ url = reverse(stepeditor,kwargs={'id':backid})
+
+ return HttpResponseRedirect(url)
+
+@user_passes_test(can_plan, login_url="/rowers/paidplans",
+ message="This functionality requires a Coach or Self-Coach plan",
+ redirect_field_name=None)
+def stepedit(request, id=0, psid=0):
+ step = get_object_or_404(PlannedSessionStep, pk=id)
+ try:
+ ps = PlannedSession.objects.get(id=psid)
+ except PlannedSession.DoesNotExist:
+ ps = None
+
+ form = StepEditorForm(instance=step)
+
+ if request.method == 'POST':
+ form = StepEditorForm(request.POST)
+ if form.is_valid():
+ if ps:
+ dd = step.asdict()
+ dd.pop('stepId')
+ for id,ss in enumerate(ps.steps['steps']):
+ ee = ss.copy()
+ ee.pop('stepId')
+
+ if (dd == ee):
+ ss['durationType'] = form.cleaned_data['durationtype']
+ ss['durationValue'] = form.cleaned_data['durationvalue']
+ ss['targetType'] = form.cleaned_data['targettype']
+ ss['targetValue'] = form.cleaned_data['targetvalue']
+ ss['targetValueLow']= form.cleaned_data['targetvaluelow']
+ ss['targetValueHigh'] = form.cleaned_data['targetvaluehigh']
+ ss['intensity'] = form.cleaned_data['intensity']
+ ss['wkt_step_name'] = form.cleaned_data['name']
+ ss['description'] = form.cleaned_data['description']
+
+ if form.cleaned_data['durationtype'] == 'Time':
+ ss['durationValue'] = form.cleaned_data['durationvalue']*60000
+ elif form.cleaned_data['durationtype'] == 'Distance':
+ ss[durationValue] = form.cleaned_data['durationvalue']*100
+
+ ss['durationValue'] = int(ss['durationValue'])
+ ps.fitfile = None
+ ps.interval_string = ""
+
+ ps.save()
+
+ step.durationtype = form.cleaned_data['durationtype']
+ step.durationvalue = form.cleaned_data['durationvalue']
+ step.targettype = form.cleaned_data['targettype']
+ step.targetvalue = form.cleaned_data['targetvalue']
+ step.targetvaluelow = form.cleaned_data['targetvaluelow']
+ step.targetvaluehigh = form.cleaned_data['targetvaluehigh']
+ step.intensity = form.cleaned_data['intensity']
+ step.name = form.cleaned_data['name']
+ step.description = form.cleaned_data['description']
+
+ if step.durationtype == 'Time':
+ step.durationvalue *= 60000
+ elif step.durationtype == 'Distance':
+ step.durationvalue *= 100
+
+ step.save()
+
+
+ if step.durationtype == 'Time':
+ form.fields['durationvalue'].initial = step.durationvalue / 60000
+ elif step.durationtype == 'Distance':
+ form.fields['durationvalue'].initial = step.durationvalue / 100
+
+
+ stepdescription = step_to_string(step.asdict(), short=False)[0]
+
+ if request.method == 'POST':
+ if 'stepsave_and_return' in request.POST:
+ url = reverse('stepeditor',kwargs = {'id': ps.id})
+ return HttpResponseRedirect(url)
+
+ breadcrumbs = [
+ {
+ 'url': reverse('template_library_view'),
+ 'name': 'Session Templates'
+ },
+ {
+ 'url': reverse('plannedsession_templateedit_view', kwargs={'id': ps.id}),
+ 'name': ps.name
+ },
+ {
+ 'url': reverse('stepeditor', kwargs={'id':ps.id}),
+ 'name': 'Edit Steps'
+ },
+ {
+ 'url': reverse('stepedit', kwargs={'psid': ps.id, 'id': step.id}),
+ 'name': 'Edit Step'
+ }
+ ]
+
+ return render(request,'stepedit.html',
+ {
+ 'step': step,
+ 'stepdescription': stepdescription,
+ 'form': form,
+ 'ps': ps,
+ 'breadcrumbs': breadcrumbs,
+ })
+
+
+
@user_passes_test(can_plan, login_url="/rowers/paidplans",
message="This functionality requires a Coach or Self-Coach plan",
redirect_field_name=None)
def stepeditor(request, id=0):
ps = get_object_or_404(PlannedSession, pk=id)
+
+ currentsteps = []
if ps.steps:
for step in ps.steps['steps']:
- print(step)
durationtype = step.get('durationType','')
durationvalue = step.get('durationValue',0)
targetvalue = step.get('targetValue',0)
@@ -3034,8 +3175,8 @@ def stepeditor(request, id=0):
targetvaluelow = targetvaluelow,
targetvaluehigh = targetvaluehigh,
intensity = intensity,
- ).count()
- if not archived_steps and durationvalue != 0:
+ )
+ if not archived_steps.count() and durationvalue != 0:
s = PlannedSessionStep(
manager = request.user,
durationtype = durationtype,
@@ -3048,7 +3189,9 @@ def stepeditor(request, id=0):
name = step.get('wkt_step_name','Step')
)
s.save()
- ps.steps = {}
+ else:
+ s = archived_steps[0]
+ currentsteps.append(s)
form = StepEditorForm()
@@ -3069,16 +3212,30 @@ def stepeditor(request, id=0):
for step in steps:
stepdescriptions[step.id] = step_to_string(step.asdict(), short=False)[0]
- print(stepdescriptions)
- print(steps)
+ breadcrumbs = [
+ {
+ 'url': reverse('template_library_view'),
+ 'name': 'Session Templates'
+ },
+ {
+ 'url': reverse('plannedsession_templateedit_view', kwargs={'id': ps.id}),
+ 'name': ps.name
+ },
+ {
+ 'url': reverse('stepeditor', kwargs={'id': ps.id}),
+ 'name': 'Edit Steps'
+ }
+ ]
return render(request, 'stepeditor.html',
{
'steps':steps,
+ 'currentsteps': currentsteps,
'stepdescriptions': stepdescriptions,
'form':form,
'ps':ps,
+ 'breadcrumbs': breadcrumbs,
})
@user_passes_test(can_plan, login_url="/rowers/paidplans",
diff --git a/static/css/rowsandall2.css b/static/css/rowsandall2.css
index da382d2c..bd6c9752 100644
--- a/static/css/rowsandall2.css
+++ b/static/css/rowsandall2.css
@@ -357,7 +357,7 @@ th.rotate > div > span {
position: relative;
overflow: hidden;
background: #878787;
- color: white;
+ /* color: white; */
padding: 10px;
padding-bottom: 40px;
}