Private
Public Access
1
0

Merge branch 'feature/coachplanning' into develop

This commit is contained in:
Sander Roosendaal
2018-02-08 22:52:47 +01:00
30 changed files with 21837 additions and 83 deletions
+15 -5
View File
@@ -10,6 +10,7 @@ from django.dispatch import receiver
from django.forms.widgets import SplitDateTimeWidget from django.forms.widgets import SplitDateTimeWidget
from django.forms.extras.widgets import SelectDateWidget from django.forms.extras.widgets import SelectDateWidget
from django.forms.formsets import BaseFormSet from django.forms.formsets import BaseFormSet
from django.contrib.admin.widgets import AdminDateWidget
from datetimewidget.widgets import DateTimeWidget from datetimewidget.widgets import DateTimeWidget
from django.core.validators import validate_email from django.core.validators import validate_email
import os import os
@@ -671,6 +672,8 @@ class GeoPoint(models.Model):
def half_year_from_now(): def half_year_from_now():
return timezone.now()+timezone.timedelta(days=182) return timezone.now()+timezone.timedelta(days=182)
def a_week_from_now():
return timezone.now()+timezone.timedelta(days=7)
# models related to training planning - draft # models related to training planning - draft
# Do we need a separate class TestTarget? # Do we need a separate class TestTarget?
@@ -819,14 +822,14 @@ class PlannedSession(models.Model):
name = models.CharField(max_length=150,blank=True) name = models.CharField(max_length=150,blank=True)
comment = models.TextField(max_length=300,blank=True, comment = models.TextField(max_length=500,blank=True,
) )
startdate = models.DateField(default=timezone.now, startdate = models.DateField(default=timezone.now,
verbose_name='Start Date') verbose_name='On or After')
enddate = models.DateField(default=timezone.now, enddate = models.DateField(default=a_week_from_now,
verbose_name='End Date') verbose_name='On or Before')
sessiontype = models.CharField(default='session', sessiontype = models.CharField(default='session',
choices=sessiontypechoices, choices=sessiontypechoices,
@@ -858,7 +861,7 @@ class PlannedSession(models.Model):
team = models.ManyToManyField(Team,blank=True) team = models.ManyToManyField(Team,blank=True)
rower = models.ManyToManyField(Rower,blank=True) rower = models.ManyToManyField(Rower,blank=True)
sessionmode = models.CharField(default='distance', sessionmode = models.CharField(default='time',
choices=sessionmodechoices, choices=sessionmodechoices,
max_length=150, max_length=150,
verbose_name='Session Mode') verbose_name='Session Mode')
@@ -884,6 +887,7 @@ class DateInput(forms.DateInput):
input_type = 'date' input_type = 'date'
class PlannedSessionForm(ModelForm): class PlannedSessionForm(ModelForm):
class Meta: class Meta:
model = PlannedSession model = PlannedSession
fields = ['startdate', fields = ['startdate',
@@ -896,6 +900,12 @@ class PlannedSessionForm(ModelForm):
'sessionunit', 'sessionunit',
'comment', 'comment',
] ]
dateTimeOptions = {
'format': 'yyyy-mm-dd',
'autoclose': True,
}
widgets = { widgets = {
'comment': forms.Textarea, 'comment': forms.Textarea,
'startdate': DateInput(), 'startdate': DateInput(),
+13 -13
View File
@@ -66,21 +66,21 @@
<div class="grid_2"> <div class="grid_2">
<input name='daterange' class="button green" type="submit" value="Submit"> </form> <input name='daterange' class="button green" type="submit" value="Submit"> </form>
</div> </div>
{% if user.is_authenticated and user|is_manager %} {% if user.is_authenticated and user|is_manager %}
<div class="grid_2 omega dropdown"> <div class="grid_2 omega dropdown">
<button class="grid_2 alpha button green small dropbtn"> <button class="grid_2 alpha button green small dropbtn">
Change Rower Change Rower
</button> </button>
<div class="dropdown-content"> <div class="dropdown-content">
{% for member in user|team_members %} {% for member in user|team_members %}
<a class="button green small" href="/rowers/u/{{ member.id }}/list-workouts/{{ startdate|date:"Y-m-d" }}/{{ enddate|date:"Y-m-d" }}">{{ member.first_name }} {{ member.last_name }}</a> <a class="button green small" href="/rowers/u/{{ member.id }}/list-workouts/{{ startdate|date:"Y-m-d" }}/{{ enddate|date:"Y-m-d" }}">{{ member.first_name }} {{ member.last_name }}</a>
{% endfor %} {% endfor %}
</div>
</div> </div>
{% else %} </div>
&nbsp; {% else %}
&nbsp;
{% endif %} {% endif %}
</div> </div>
+34 -19
View File
@@ -1,5 +1,6 @@
{% extends "base.html" %} {% extends "base.html" %}
{% load staticfiles %} {% load staticfiles %}
{% load rowerfilters %}
{% block title %}New Planned Session{% endblock %} {% block title %}New Planned Session{% endblock %}
@@ -13,7 +14,7 @@
<h1>Create Session for {{ rower.user.first_name }} {{ rower.user.last_name }}</h1> <h1>Create Session for {{ rower.user.first_name }} {{ rower.user.last_name }}</h1>
</div> </div>
<div id="timeperiod" class="grid_2 dropdown"> <div id="timeperiod" class="grid_2 dropdown">
<button class="grid_2 alpha button gray small dropbtn">Time Period</button> <button class="grid_2 alpha button gray small dropbtn">Select Time Period ({{ timeperiod|verbosetimeperiod }})</button>
<div class="dropdown-content"> <div class="dropdown-content">
<a class="button gray small alpha" <a class="button gray small alpha"
href="/rowers/sessions/create/today/rower/{{ rower.id }}"> href="/rowers/sessions/create/today/rower/{{ rower.id }}">
@@ -37,25 +38,22 @@
</a> </a>
</div> </div>
</div> </div>
</div> {% if user.is_authenticated and user|is_manager %}
<div class="grid_12 alpha"> <div class="grid_2 dropdown">
<div class="grid_6 alpha"> <button class="grid_2 alpha button green small dropbtn">
<form enctype="multipart/form-data" action="{{ formloc }}" method="post"> Change Rower
{% if form.errors %} </button>
<p style="color: red;"> <div class="dropdown-content">
Please correct the error{{ form.errors|pluralize }} below. {% for member in user|team_rowers %}
</p> <a class="button green small" href="/rowers/sessions/create/{{ timeperiod }}/rower/{{ member.id }}">{{ member.user.first_name }} {{ member.user.last_name }}</a>
{% endif %} {% endfor %}
<table>
{{ form.as_table }}
</table>
{% csrf_token %}
<div id="formbutton" class="grid_1 prefix_4 suffix_1">
<input class="button green" type="submit" value="Submit">
</div>
</div> </div>
<div id="right" class="grid_6 omega"> </div>
{% endif %}
</div>
<div class="grid_12 alpha">
<div id="right" class="grid_6 alpha">
<h1>Plan</h1> <h1>Plan</h1>
<p> <p>
Click on session name to view Click on session name to view
@@ -107,6 +105,23 @@
<div class="grid_6 omega">
<h1>New Session</h1>
<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 %}
<table>
{{ form.as_table }}
</table>
{% csrf_token %}
<div id="formbutton" class="grid_1 prefix_4 suffix_1">
<input class="button green" type="submit" value="Submit">
</div>
</form> </form>
</div>
</div> </div>
{% endblock %} {% endblock %}
+48 -31
View File
@@ -12,7 +12,7 @@
<h1>Plan for {{ rower.user.first_name }} {{ rower.user.last_name }}</h1> <h1>Plan for {{ rower.user.first_name }} {{ rower.user.last_name }}</h1>
</div> </div>
<div id="timeperiod" class="grid_2 dropdown"> <div id="timeperiod" class="grid_2 dropdown">
<button class="grid_2 alpha button gray small dropbtn">Time Period</button> <button class="grid_2 alpha button gray small dropbtn">Select Time Period ({{ timeperiod|verbosetimeperiod }})</button>
<div class="dropdown-content"> <div class="dropdown-content">
<a class="button gray small alpha" <a class="button gray small alpha"
href="/rowers/sessions/today/rower/{{ rower.id }}"> href="/rowers/sessions/today/rower/{{ rower.id }}">
@@ -36,51 +36,44 @@
</a> </a>
</div> </div>
</div> </div>
{% if user.is_authenticated and user|is_manager %}
<div class="grid_2 dropdown">
<button class="grid_2 alpha button green small dropbtn">
Change Rower
</button>
<div class="dropdown-content">
{% for member in user|team_rowers %}
<a class="button green small" href="/rowers/sessions/{{ timeperiod }}/rower/{{ member.id }}">{{ member.user.first_name }} {{ member.user.last_name }}</a>
{% endfor %}
</div>
</div>
{% endif %}
<div class="grid_12 alpha"> <div class="grid_12 alpha">
{% if plannedsessions %} {% if plannedsessions %}
<p> <p>
Click on session name to view, edit to change the session and on the Click on session name to view, edit to change the session and on the
traffic light symbol to add workouts to the session traffic light symbol to add workouts to the session
</p> </p>
<table width="80%" class="listtable shortpadded"> <table width="90%" class="listtable shortpadded">
<thead> <thead>
<tr> <tr>
<th>After</th>
<th>Before</th>
<th>Name</th>
<th>Edit</th>
<th>Value</th>
<th>&nbsp;</th>
<th>Type</th>
<th>Status</th> <th>Status</th>
<th>On or After</th>
<th>On or Before</th>
<th>Name</th>
<th>Type</th>
<th>Edit</th>
<th>Planned</th>
<th>Actual</th>
<th>&nbsp;</th>
<th>Completion Date</th>
<th> <th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
{% for ps in plannedsessions %} {% for ps in plannedsessions %}
<tr> <tr>
<td> {{ ps.startdate|date:"Y-m-d" }} </td>
<td> {{ ps.enddate|date:"Y-m-d" }} </td>
<td>
{% if ps.name != '' %}
<a class="small"
href="/rowers/sessions/{{ ps.id }}">{{ ps.name }}</a>
{% else %}
<a class="small"
href="/rowers/sessions/{{ ps.id }}">Unnamed Session</a>
{% endif %}
</td>
<td>
{% if ps.manager == request.user %}
<a class="small"
href="/rowers/sessions/{{ ps.id }}/edit">Edit</a>
{% else %}
&nbsp;
{% endif %}
</td>
<td> {{ ps.sessionvalue }} </td>
<td> {{ ps.sessionunit }} </td>
<td> {{ ps.sessiontype }} </td>
<td> <td>
{% if completeness|lookup:ps.id == 'not done' %} {% if completeness|lookup:ps.id == 'not done' %}
<a class="white dot" href="/rowers/sessions/manage/{{ timeperiod }}/rower/{{ rower.id }}/session/{{ ps.id }}">&nbsp;</a> <a class="white dot" href="/rowers/sessions/manage/{{ timeperiod }}/rower/{{ rower.id }}/session/{{ ps.id }}">&nbsp;</a>
@@ -92,6 +85,30 @@
<a class="red dot" href="/rowers/sessions/manage/{{ timeperiod }}/rower/{{ rower.id }}/session/{{ ps.id }}">&nbsp;</a> <a class="red dot" href="/rowers/sessions/manage/{{ timeperiod }}/rower/{{ rower.id }}/session/{{ ps.id }}">&nbsp;</a>
{% endif %} {% endif %}
</td> </td>
<td> {{ ps.startdate|date:"Y-m-d" }} </td>
<td> {{ ps.enddate|date:"Y-m-d" }} </td>
<td>
{% if ps.name != '' %}
<a class="small"
href="/rowers/sessions/{{ ps.id }}">{{ ps.name }}</a>
{% else %}
<a class="small"
href="/rowers/sessions/{{ ps.id }}">Unnamed Session</a>
{% endif %}
</td>
<td> {{ ps.sessiontype }} </td>
<td>
{% if ps.manager == request.user %}
<a class="small"
href="/rowers/sessions/{{ ps.id }}/edit">Edit</a>
{% else %}
&nbsp;
{% endif %}
</td>
<td> {{ ps.sessionvalue }} </td>
<td> {{ actualvalue|lookup:ps.id }}</td>
<td> {{ ps.sessionunit }} </td>
<td> {{ completiondate|lookup:ps.id|date:"Y-m-d" }}</td>
</tr> </tr>
{% endfor %} {% endfor %}
</tbody> </tbody>
+15 -1
View File
@@ -20,12 +20,13 @@
<div class="grid_12 alpha"> <div class="grid_12 alpha">
{% include "planningbuttons.html" %} {% include "planningbuttons.html" %}
</div> </div>
<div class="grid_12 alpha">
<div class="grid_6 alpha"> <div class="grid_6 alpha">
<h1>Manage Plan Execution for {{ rower.user.first_name }} {{ rower.user.last_name }}</h1> <h1>Manage Plan Execution for {{ rower.user.first_name }} {{ rower.user.last_name }}</h1>
</div> </div>
<div id="timeperiod" class="grid_2 dropdown"> <div id="timeperiod" class="grid_2 dropdown">
<button class="grid_2 alpha button gray small dropbtn">Time Period</button> <button class="grid_2 alpha button gray small dropbtn">Select Time Period ({{ timeperiod|verbosetimeperiod }})</button>
<div class="dropdown-content"> <div class="dropdown-content">
<a class="button gray small alpha" <a class="button gray small alpha"
href="/rowers/sessions/manage/today/rower/{{ rower.id }}"> href="/rowers/sessions/manage/today/rower/{{ rower.id }}">
@@ -48,6 +49,19 @@
Last Month Last Month
</a> </a>
</div> </div>
</div>
{% if user.is_authenticated and user|is_manager %}
<div class="grid_2 dropdown">
<button class="grid_2 alpha button green small dropbtn">
Change Rower
</button>
<div class="dropdown-content">
{% for member in user|team_rowers %}
<a class="button green small" href="/rowers/sessions/manage/{{ timeperiod }}/rower/{{ member.id }}">{{ member.user.first_name }} {{ member.user.last_name }}</a>
{% endfor %}
</div>
{% endif %}
</div>
</div> </div>
<div class="grid_12 alpha"> <div class="grid_12 alpha">
<p>Select one session on the left, and one or more workouts on the right <p>Select one session on the left, and one or more workouts on the right
+9 -3
View File
@@ -13,16 +13,22 @@
<div class="grid_2"> <div class="grid_2">
<p> <p>
{% if timeperiod and rower %} {% if timeperiod and rower %}
<a class="button gray small" href="/rowers/sessions/manage/{{ timeperiod }}/rower/{{ rower.id }}">Manage Sessions</a> <a class="button gray small" href="/rowers/sessions/manage/{{ timeperiod }}/rower/{{ rower.id }}">Link to Workouts</a>
{% elif timeperiod %} {% elif timeperiod %}
<a class="button gray small" href="/rowers/sessions/manage/{{ timeperiod }}">Manage Sessions</a> <a class="button gray small" href="/rowers/sessions/manage/{{ timeperiod }}">Link to Workouts</a>
{% else %} {% else %}
<a class="button gray small" href="/rowers/sessions/manage">Manage Sessions</a> <a class="button gray small" href="/rowers/sessions/manage">Link to Workouts</a>
{% endif %} {% endif %}
</p> </p>
</div> </div>
<div class="grid_2 suffix_6 omega"> <div class="grid_2 suffix_6 omega">
<p> <p>
{% if timeperiod and rower %}
<a class="button gray small" href="/rowers/sessions/create/{{ timeperiod }}/rower/{{ rower.id }}">Add Session</a>
{% elif timeperiod %}
<a class="button gray small" href="/rowers/sessions/create/{{ timeperiod }}">Add Session</a>
{% else %}
<a class="button gray small" href="/rowers/sessions/create">Add Session</a> <a class="button gray small" href="/rowers/sessions/create">Add Session</a>
{% endif %}
</p> </p>
</div> </div>
+32 -1
View File
@@ -145,10 +145,41 @@ def team_members(user):
if therower.rowerplan != 'coach': if therower.rowerplan != 'coach':
return [] return []
teams = Team.objects.filter(manager=user) teams = Team.objects.filter(manager=user)
members = Rower.objects.filter(team__in=teams) members = Rower.objects.filter(team__in=teams).distinct()
return [rower.user for rower in members] return [rower.user for rower in members]
except TypeError: except TypeError:
return [] return []
return [] return []
@register.filter
def team_rowers(user):
try:
therower = Rower.objects.get(user=user)
if therower.rowerplan != 'coach':
return []
teams = Team.objects.filter(manager=user)
members = Rower.objects.filter(team__in=teams).distinct()
return members
except TypeError:
return []
return []
@register.filter
def verbosetimeperiod(timeperiod):
table = {
'today':'Today',
'thisweek': 'This Week',
'thismonth': 'This Month',
'lastmonth': 'Last Month',
'lastweek': 'Last Week',
}
try:
verbose = table[timeperiod]
except KeyError:
verbose = timeperiod
return verbose
+30 -9
View File
@@ -11712,8 +11712,7 @@ def agegrouprecordview(request,sex='male',weightcategory='hwt',
# Individual user creates training for himself # Individual user creates training for himself
@user_passes_test(hasplannedsessions,login_url="/rowers/planmembership/", @user_passes_test(hasplannedsessions,login_url="/rowers/planmembership/",
redirect_field_name=None) redirect_field_name=None)
def plannedsession_create_view(request,timeperiod='today',rowerid=0): def plannedsession_create_view(request,timeperiod='thisweek',rowerid=0):
if rowerid==0: if rowerid==0:
r = getrower(request.user) r = getrower(request.user)
else: else:
@@ -11759,7 +11758,11 @@ def plannedsession_create_view(request,timeperiod='today',rowerid=0):
add_rower_session(r,ps) add_rower_session(r,ps)
url = reverse(plannedsession_create_view) url = reverse(plannedsession_create_view,
kwargs = {
'rowerid':r.id,
'timeperiod':timeperiod,
})
return HttpResponseRedirect(url) return HttpResponseRedirect(url)
else: else:
sessioncreateform = PlannedSessionForm() sessioncreateform = PlannedSessionForm()
@@ -11773,10 +11776,11 @@ def plannedsession_create_view(request,timeperiod='today',rowerid=0):
'form':sessioncreateform, 'form':sessioncreateform,
'plannedsessions':sps, 'plannedsessions':sps,
'rower':r, 'rower':r,
'timeperiod':timeperiod,
}) })
@login_required() @login_required()
def plannedsessions_view(request,timeperiod='today',rowerid=0): def plannedsessions_view(request,timeperiod='thisweek',rowerid=0):
if rowerid==0: if rowerid==0:
r = getrower(request.user) r = getrower(request.user)
@@ -11793,10 +11797,19 @@ def plannedsessions_view(request,timeperiod='today',rowerid=0):
sps = get_sessions(r,startdate=startdate,enddate=enddate) sps = get_sessions(r,startdate=startdate,enddate=enddate)
completeness = {} completeness = {}
actualvalue = {}
completiondate = {}
for ps in sps: for ps in sps:
ratio,status = is_session_complete(r,ps) ratio,status = is_session_complete(r,ps)
actualvalue[ps.id] = int(ps.sessionvalue*ratio)
completeness[ps.id] = status completeness[ps.id] = status
ws = Workout.objects.filter(user=r,plannedsession=ps)
if len(ws):
date = min([w.date for w in ws])
completiondate[ps.id] = date
else:
completiondate[ps.id] = ''
return render(request,'plannedsessions.html', return render(request,'plannedsessions.html',
{ {
@@ -11805,10 +11818,12 @@ def plannedsessions_view(request,timeperiod='today',rowerid=0):
'rower':r, 'rower':r,
'timeperiod':timeperiod, 'timeperiod':timeperiod,
'completeness':completeness, 'completeness':completeness,
'actualvalue':actualvalue,
'completiondate':completiondate,
}) })
@login_required() @login_required()
def plannedsessions_manage_view(request,timeperiod='today',rowerid=0, def plannedsessions_manage_view(request,timeperiod='thisweek',rowerid=0,
initialsession=0): initialsession=0):
is_ajax = False is_ajax = False
@@ -11829,9 +11844,15 @@ def plannedsessions_manage_view(request,timeperiod='today',rowerid=0,
sps = get_sessions(r,startdate=startdate,enddate=enddate) sps = get_sessions(r,startdate=startdate,enddate=enddate)
if initialsession==0: if initialsession==0:
initialsession=sps[0].id try:
initialsession=sps[0].id
except IndexError:
initialsession=0
ps0 = PlannedSession.objects.get(id=initialsession) if initialsession:
ps0 = PlannedSession.objects.get(id=initialsession)
else:
ps0 = None
ws = Workout.objects.filter( ws = Workout.objects.filter(
user=r,date__gte=startdate, user=r,date__gte=startdate,
@@ -11925,7 +11946,7 @@ def plannedsessions_manage_view(request,timeperiod='today',rowerid=0,
@user_passes_test(hasplannedsessions,login_url="/rowers/planmembership/", @user_passes_test(hasplannedsessions,login_url="/rowers/planmembership/",
redirect_field_name=None) redirect_field_name=None)
def plannedsession_clone_view(request,id=0,rowerid=0, def plannedsession_clone_view(request,id=0,rowerid=0,
timeperiod='today'): timeperiod='thisweek'):
if rowerid==0: if rowerid==0:
r = getrower(request.user) r = getrower(request.user)
else: else:
@@ -11970,7 +11991,7 @@ def plannedsession_clone_view(request,id=0,rowerid=0,
# Edit an existing planned session # Edit an existing planned session
@user_passes_test(hasplannedsessions,login_url="/rowers/planmembership/", @user_passes_test(hasplannedsessions,login_url="/rowers/planmembership/",
redirect_field_name=None) redirect_field_name=None)
def plannedsession_edit_view(request,id=0,timeperiod='today',rowerid=0): def plannedsession_edit_view(request,id=0,timeperiod='thisweek',rowerid=0):
if rowerid==0: if rowerid==0:
r = getrower(request.user) r = getrower(request.user)
+1
View File
@@ -57,6 +57,7 @@ INSTALLED_APPS = [
'translation_manager', 'translation_manager',
'django_mailbox', 'django_mailbox',
'rest_framework', 'rest_framework',
'datetimewidget',
'rest_framework_swagger', 'rest_framework_swagger',
'oauth2_provider', 'oauth2_provider',
'corsheaders', 'corsheaders',
+2050
View File
File diff suppressed because it is too large Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+330
View File
@@ -0,0 +1,330 @@
/*!
* Bootstrap Reboot v4.0.0 (https://getbootstrap.com)
* Copyright 2011-2018 The Bootstrap Authors
* Copyright 2011-2018 Twitter, Inc.
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
* Forked from Normalize.css, licensed MIT (https://github.com/necolas/normalize.css/blob/master/LICENSE.md)
*/
*,
*::before,
*::after {
box-sizing: border-box;
}
html {
font-family: sans-serif;
line-height: 1.15;
-webkit-text-size-adjust: 100%;
-ms-text-size-adjust: 100%;
-ms-overflow-style: scrollbar;
-webkit-tap-highlight-color: transparent;
}
@-ms-viewport {
width: device-width;
}
article, aside, dialog, figcaption, figure, footer, header, hgroup, main, nav, section {
display: block;
}
body {
margin: 0;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
font-size: 1rem;
font-weight: 400;
line-height: 1.5;
color: #212529;
text-align: left;
background-color: #fff;
}
[tabindex="-1"]:focus {
outline: 0 !important;
}
hr {
box-sizing: content-box;
height: 0;
overflow: visible;
}
h1, h2, h3, h4, h5, h6 {
margin-top: 0;
margin-bottom: 0.5rem;
}
p {
margin-top: 0;
margin-bottom: 1rem;
}
abbr[title],
abbr[data-original-title] {
text-decoration: underline;
-webkit-text-decoration: underline dotted;
text-decoration: underline dotted;
cursor: help;
border-bottom: 0;
}
address {
margin-bottom: 1rem;
font-style: normal;
line-height: inherit;
}
ol,
ul,
dl {
margin-top: 0;
margin-bottom: 1rem;
}
ol ol,
ul ul,
ol ul,
ul ol {
margin-bottom: 0;
}
dt {
font-weight: 700;
}
dd {
margin-bottom: .5rem;
margin-left: 0;
}
blockquote {
margin: 0 0 1rem;
}
dfn {
font-style: italic;
}
b,
strong {
font-weight: bolder;
}
small {
font-size: 80%;
}
sub,
sup {
position: relative;
font-size: 75%;
line-height: 0;
vertical-align: baseline;
}
sub {
bottom: -.25em;
}
sup {
top: -.5em;
}
a {
color: #007bff;
text-decoration: none;
background-color: transparent;
-webkit-text-decoration-skip: objects;
}
a:hover {
color: #0056b3;
text-decoration: underline;
}
a:not([href]):not([tabindex]) {
color: inherit;
text-decoration: none;
}
a:not([href]):not([tabindex]):hover, a:not([href]):not([tabindex]):focus {
color: inherit;
text-decoration: none;
}
a:not([href]):not([tabindex]):focus {
outline: 0;
}
pre,
code,
kbd,
samp {
font-family: monospace, monospace;
font-size: 1em;
}
pre {
margin-top: 0;
margin-bottom: 1rem;
overflow: auto;
-ms-overflow-style: scrollbar;
}
figure {
margin: 0 0 1rem;
}
img {
vertical-align: middle;
border-style: none;
}
svg:not(:root) {
overflow: hidden;
}
table {
border-collapse: collapse;
}
caption {
padding-top: 0.75rem;
padding-bottom: 0.75rem;
color: #6c757d;
text-align: left;
caption-side: bottom;
}
th {
text-align: inherit;
}
label {
display: inline-block;
margin-bottom: .5rem;
}
button {
border-radius: 0;
}
button:focus {
outline: 1px dotted;
outline: 5px auto -webkit-focus-ring-color;
}
input,
button,
select,
optgroup,
textarea {
margin: 0;
font-family: inherit;
font-size: inherit;
line-height: inherit;
}
button,
input {
overflow: visible;
}
button,
select {
text-transform: none;
}
button,
html [type="button"],
[type="reset"],
[type="submit"] {
-webkit-appearance: button;
}
button::-moz-focus-inner,
[type="button"]::-moz-focus-inner,
[type="reset"]::-moz-focus-inner,
[type="submit"]::-moz-focus-inner {
padding: 0;
border-style: none;
}
input[type="radio"],
input[type="checkbox"] {
box-sizing: border-box;
padding: 0;
}
input[type="date"],
input[type="time"],
input[type="datetime-local"],
input[type="month"] {
-webkit-appearance: listbox;
}
textarea {
overflow: auto;
resize: vertical;
}
fieldset {
min-width: 0;
padding: 0;
margin: 0;
border: 0;
}
legend {
display: block;
width: 100%;
max-width: 100%;
padding: 0;
margin-bottom: .5rem;
font-size: 1.5rem;
line-height: inherit;
color: inherit;
white-space: normal;
}
progress {
vertical-align: baseline;
}
[type="number"]::-webkit-inner-spin-button,
[type="number"]::-webkit-outer-spin-button {
height: auto;
}
[type="search"] {
outline-offset: -2px;
-webkit-appearance: none;
}
[type="search"]::-webkit-search-cancel-button,
[type="search"]::-webkit-search-decoration {
-webkit-appearance: none;
}
::-webkit-file-upload-button {
font: inherit;
-webkit-appearance: button;
}
output {
display: inline-block;
}
summary {
display: list-item;
cursor: pointer;
}
template {
display: none;
}
[hidden] {
display: none !important;
}
/*# sourceMappingURL=bootstrap-reboot.css.map */
File diff suppressed because one or more lines are too long
+8
View File
@@ -0,0 +1,8 @@
/*!
* Bootstrap Reboot v4.0.0 (https://getbootstrap.com)
* Copyright 2011-2018 The Bootstrap Authors
* Copyright 2011-2018 Twitter, Inc.
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
* Forked from Normalize.css, licensed MIT (https://github.com/necolas/normalize.css/blob/master/LICENSE.md)
*/*,::after,::before{box-sizing:border-box}html{font-family:sans-serif;line-height:1.15;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%;-ms-overflow-style:scrollbar;-webkit-tap-highlight-color:transparent}@-ms-viewport{width:device-width}article,aside,dialog,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}body{margin:0;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol";font-size:1rem;font-weight:400;line-height:1.5;color:#212529;text-align:left;background-color:#fff}[tabindex="-1"]:focus{outline:0!important}hr{box-sizing:content-box;height:0;overflow:visible}h1,h2,h3,h4,h5,h6{margin-top:0;margin-bottom:.5rem}p{margin-top:0;margin-bottom:1rem}abbr[data-original-title],abbr[title]{text-decoration:underline;-webkit-text-decoration:underline dotted;text-decoration:underline dotted;cursor:help;border-bottom:0}address{margin-bottom:1rem;font-style:normal;line-height:inherit}dl,ol,ul{margin-top:0;margin-bottom:1rem}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}dt{font-weight:700}dd{margin-bottom:.5rem;margin-left:0}blockquote{margin:0 0 1rem}dfn{font-style:italic}b,strong{font-weight:bolder}small{font-size:80%}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}a{color:#007bff;text-decoration:none;background-color:transparent;-webkit-text-decoration-skip:objects}a:hover{color:#0056b3;text-decoration:underline}a:not([href]):not([tabindex]){color:inherit;text-decoration:none}a:not([href]):not([tabindex]):focus,a:not([href]):not([tabindex]):hover{color:inherit;text-decoration:none}a:not([href]):not([tabindex]):focus{outline:0}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}pre{margin-top:0;margin-bottom:1rem;overflow:auto;-ms-overflow-style:scrollbar}figure{margin:0 0 1rem}img{vertical-align:middle;border-style:none}svg:not(:root){overflow:hidden}table{border-collapse:collapse}caption{padding-top:.75rem;padding-bottom:.75rem;color:#6c757d;text-align:left;caption-side:bottom}th{text-align:inherit}label{display:inline-block;margin-bottom:.5rem}button{border-radius:0}button:focus{outline:1px dotted;outline:5px auto -webkit-focus-ring-color}button,input,optgroup,select,textarea{margin:0;font-family:inherit;font-size:inherit;line-height:inherit}button,input{overflow:visible}button,select{text-transform:none}[type=reset],[type=submit],button,html [type=button]{-webkit-appearance:button}[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner,button::-moz-focus-inner{padding:0;border-style:none}input[type=checkbox],input[type=radio]{box-sizing:border-box;padding:0}input[type=date],input[type=datetime-local],input[type=month],input[type=time]{-webkit-appearance:listbox}textarea{overflow:auto;resize:vertical}fieldset{min-width:0;padding:0;margin:0;border:0}legend{display:block;width:100%;max-width:100%;padding:0;margin-bottom:.5rem;font-size:1.5rem;line-height:inherit;color:inherit;white-space:normal}progress{vertical-align:baseline}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{outline-offset:-2px;-webkit-appearance:none}[type=search]::-webkit-search-cancel-button,[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{font:inherit;-webkit-appearance:button}output{display:inline-block}summary{display:list-item;cursor:pointer}template{display:none}[hidden]{display:none!important}
/*# sourceMappingURL=bootstrap-reboot.min.css.map */
File diff suppressed because one or more lines are too long
+8975
View File
File diff suppressed because it is too large Load Diff
File diff suppressed because one or more lines are too long
+7
View File
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+6328
View File
File diff suppressed because it is too large Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+3894
View File
File diff suppressed because it is too large Load Diff
File diff suppressed because one or more lines are too long
+7
View File
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+16
View File
@@ -11,6 +11,20 @@
<head> <head>
{% block scripts %} {% endblock %} {% block scripts %} {% endblock %}
<script type="text/javascript" src="/admin/jsi18n/"></script>
<script type="text/javascript" src="/static/admin/js/core.js"></script>
<script type="text/javascript" src="/static/admin/js/admin/RelatedObjectLookups.js"> </script>
<script type="text/javascript" src="/static/admin/js/jquery.min.js"></script>
<script type="text/javascript" src="/static/admin/js/jquery.init.js"></script>
<script type="text/javascript" src="/static/admin/js/actions.min.js"></script>
<script type="text/javascript" src="/static/admin/js/calendar.js"></script>
<script type="text/javascript" src="/static/admin/js/urlify.js"></script>
<script type="text/javascript" src="/static/admin/js/prepopulate.js"></script>
<script type="text/javascript" src="/static/admin/js/vendor/xregexp/xregexp.min.js"></script>
<script type="text/javascript" src="/static/admin/js/SelectBox.js"></script>
<script type="text/javascript" src="/static/admin/js/SelectFilter2.js"></script>
<script type="text/javascript" src="/static/admin/js/admin/DateTimeShortcuts.js"></script>
<script type="text/javascript" src="/static/admin/js/inlines.js"></script>
<script src="/static/cookielaw/js/cookielaw.js"></script> <script src="/static/cookielaw/js/cookielaw.js"></script>
{% analytical_head_top %} {% analytical_head_top %}
{% if GOOGLE_ANALYTICS_PROPERTY_ID %} {% if GOOGLE_ANALYTICS_PROPERTY_ID %}
@@ -38,6 +52,8 @@
<meta property="fb:app_id" content="694685920739849" /> <meta property="fb:app_id" content="694685920739849" />
<meta property="og:title" content="{% block og_title %}Rowsandall{% endblock %}" /> <meta property="og:title" content="{% block og_title %}Rowsandall{% endblock %}" />
<meta property="og:description" content="{% block og_description %}Rowsandall: Free Data and Analysis. For Rowers. By Rowers.{% endblock %}" /> <meta property="og:description" content="{% block og_description %}Rowsandall: Free Data and Analysis. For Rowers. By Rowers.{% endblock %}" />
<link rel="stylesheet" type="text/css" href="/static/admin/css/forms.css"/>
<link rel="stylesheet" type="text/css" href="/static/admin/css/widgets.css"/>
<link rel="stylesheet" href="/static/css/reset.css" /> <link rel="stylesheet" href="/static/css/reset.css" />
<link rel="stylesheet" href="/static/css/text.css" /> <link rel="stylesheet" href="/static/css/text.css" />
<link rel="stylesheet" href="/static/css/960_12_col.css" /> <link rel="stylesheet" href="/static/css/960_12_col.css" />