mirror of https://github.com/snachodog/mybuddy.git
Move timeline code to core and integrate with Child detail view.
This commit is contained in:
parent
1c5278cebf
commit
162f117cef
|
@ -3,3 +3,12 @@
|
||||||
max-width: 150px;
|
max-width: 150px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@include media-breakpoint-up(md) {
|
||||||
|
#view-child {
|
||||||
|
.child-detail-column {
|
||||||
|
position: fixed;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -118,7 +118,7 @@ $card-shadow: rgba(0, 0, 0, .175);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (max-width: 767px) {
|
@include media-breakpoint-down(md) {
|
||||||
.timeline {
|
.timeline {
|
||||||
&::before {
|
&::before {
|
||||||
left: 40px;
|
left: 40px;
|
|
@ -9,13 +9,53 @@
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<div class="jumbotron text-center">
|
<div class="child-detail-column">
|
||||||
<img src="{% static 'babybuddy/img/core/child-placeholder.png' %}" class="child-photo img-fluid rounded-circle" />
|
<div class="row">
|
||||||
<div class="child-name display-4">{{ object }}</div>
|
<div class="col-lg-4 col-md-6 pb-3 text-center">
|
||||||
<p class="lead">
|
<img src="{% static 'babybuddy/img/core/child-placeholder.png' %}" class="child-photo img-fluid rounded-circle" />
|
||||||
Born <span class="text-secondary">{{ object.birth_date }}</span><br/>
|
<div class="child-name display-4">{{ object }}</div>
|
||||||
Age <span class="text-secondary">{{ object.birth_date|timesince }}</span>
|
<p class="lead">
|
||||||
</p>
|
Born <span class="text-secondary">{{ object.birth_date }}</span><br/>
|
||||||
{% include 'dashboard/child_button_group.html' %}
|
Age <span class="text-secondary">{{ object.birth_date|timesince }}</span>
|
||||||
|
</p>
|
||||||
|
{% include 'dashboard/child_button_group.html' %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-lg-8 offset-lg-4 col-md-6 offset-md-6">
|
||||||
|
<h3 class="text-center">
|
||||||
|
{% if date_previous %}
|
||||||
|
<a class="btn btn-sm btn-default" href="?date={{ date_previous|date:"Y-m-d" }}" aria-label="Previous">
|
||||||
|
<i class="icon icon-chevron-left" aria-hidden="true"></i>
|
||||||
|
<span class="sr-only">Previous</span>
|
||||||
|
</a>
|
||||||
|
{% endif %}
|
||||||
|
{{ date|date }}
|
||||||
|
{% if date_next %}
|
||||||
|
<a class="btn btn-sm btn-default" href="?date={{ date_next|date:"Y-m-d" }}" aria-label="Next">
|
||||||
|
<i class="icon icon-chevron-right" aria-hidden="true"></i>
|
||||||
|
<span class="sr-only">Next</span>
|
||||||
|
</a>
|
||||||
|
{% endif %}
|
||||||
|
</h3>
|
||||||
|
<ul class="timeline m-auto">
|
||||||
|
{% for object in timeline_objects %}
|
||||||
|
<li{% cycle "" ' class="timeline-inverted"' %}>
|
||||||
|
<div class="timeline-badge {% if object.type == "start" %}bg-success{% elif object.type == "end" %}bg-danger{% else %}bg-info{% endif %}">
|
||||||
|
<i class="icon icon-{{ object.model_name }}"></i>
|
||||||
|
</div>
|
||||||
|
<div class="card text-right">
|
||||||
|
<div class="card-body">
|
||||||
|
{{ object.event }}
|
||||||
|
</div>
|
||||||
|
<div class="card-footer text-muted">
|
||||||
|
{{ object.time|timesince }} ago ({{ object.time|time }})
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
{% endfor %}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% endblock %}
|
{% endblock %}
|
|
@ -6,9 +6,9 @@ from django.utils import timezone
|
||||||
from core.models import DiaperChange, Feeding, Sleep, TummyTime
|
from core.models import DiaperChange, Feeding, Sleep, TummyTime
|
||||||
|
|
||||||
|
|
||||||
def timeline(child, date):
|
def get_objects(child, date):
|
||||||
"""
|
"""
|
||||||
Create a time-sorted dictionary for all events for a child.
|
Create a time-sorted dictionary of all events for a child.
|
||||||
:param child: an instance of a Child.
|
:param child: an instance of a Child.
|
||||||
:param date: a DateTime instance for the day to be summarized.
|
:param date: a DateTime instance for the day to be summarized.
|
||||||
:returns: a list of the day's events.
|
:returns: a list of the day's events.
|
109
core/views.py
109
core/views.py
|
@ -3,19 +3,18 @@ from __future__ import unicode_literals
|
||||||
|
|
||||||
from django.contrib.auth.mixins import PermissionRequiredMixin
|
from django.contrib.auth.mixins import PermissionRequiredMixin
|
||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
|
from django.utils import timezone
|
||||||
from django.views.generic.base import RedirectView
|
from django.views.generic.base import RedirectView
|
||||||
from django.views.generic.detail import DetailView
|
from django.views.generic.detail import DetailView
|
||||||
from django.views.generic.edit import CreateView, UpdateView, DeleteView
|
from django.views.generic.edit import CreateView, UpdateView, DeleteView
|
||||||
|
|
||||||
from django_filters.views import FilterView
|
from django_filters.views import FilterView
|
||||||
|
|
||||||
from .models import Child, DiaperChange, Feeding, Note, Sleep, Timer, TummyTime
|
from core import forms, models, timeline
|
||||||
from .forms import (ChildForm, ChildDeleteForm, DiaperChangeForm, FeedingForm,
|
|
||||||
SleepForm, TimerForm, TummyTimeForm)
|
|
||||||
|
|
||||||
|
|
||||||
class ChildList(PermissionRequiredMixin, FilterView):
|
class ChildList(PermissionRequiredMixin, FilterView):
|
||||||
model = Child
|
model = models.Child
|
||||||
template_name = 'core/child_list.html'
|
template_name = 'core/child_list.html'
|
||||||
permission_required = ('core.view_child',)
|
permission_required = ('core.view_child',)
|
||||||
paginate_by = 10
|
paginate_by = 10
|
||||||
|
@ -23,34 +22,46 @@ class ChildList(PermissionRequiredMixin, FilterView):
|
||||||
|
|
||||||
|
|
||||||
class ChildAdd(PermissionRequiredMixin, CreateView):
|
class ChildAdd(PermissionRequiredMixin, CreateView):
|
||||||
model = Child
|
model = models.Child
|
||||||
permission_required = ('core.add_child',)
|
permission_required = ('core.add_child',)
|
||||||
form_class = ChildForm
|
form_class = forms.ChildForm
|
||||||
success_url = '/children'
|
success_url = '/children'
|
||||||
|
|
||||||
|
|
||||||
class ChildDetail(PermissionRequiredMixin, DetailView):
|
class ChildDetail(PermissionRequiredMixin, DetailView):
|
||||||
model = Child
|
model = models.Child
|
||||||
permission_required = ('core.view_child',)
|
permission_required = ('core.view_child',)
|
||||||
|
|
||||||
|
def get_context_data(self, **kwargs):
|
||||||
|
context = super(ChildDetail, self).get_context_data(**kwargs)
|
||||||
|
date = self.request.GET.get('date', str(timezone.localdate()))
|
||||||
|
date = timezone.datetime.strptime(date, '%Y-%m-%d')
|
||||||
|
date = timezone.localtime(timezone.make_aware(date))
|
||||||
|
context['timeline_objects'] = timeline.get_objects(self.object, date)
|
||||||
|
context['date'] = date
|
||||||
|
context['date_previous'] = date - timezone.timedelta(days=1)
|
||||||
|
if date.date() < timezone.localdate():
|
||||||
|
context['date_next'] = date + timezone.timedelta(days=1)
|
||||||
|
return context
|
||||||
|
|
||||||
|
|
||||||
class ChildUpdate(PermissionRequiredMixin, UpdateView):
|
class ChildUpdate(PermissionRequiredMixin, UpdateView):
|
||||||
model = Child
|
model = models.Child
|
||||||
permission_required = ('core.change_child',)
|
permission_required = ('core.change_child',)
|
||||||
form_class = ChildForm
|
form_class = forms.ChildForm
|
||||||
success_url = '/children'
|
success_url = '/children'
|
||||||
|
|
||||||
|
|
||||||
class ChildDelete(PermissionRequiredMixin, UpdateView):
|
class ChildDelete(PermissionRequiredMixin, UpdateView):
|
||||||
model = Child
|
model = models.Child
|
||||||
form_class = ChildDeleteForm
|
form_class = forms.ChildDeleteForm
|
||||||
template_name = 'core/child_confirm_delete.html'
|
template_name = 'core/child_confirm_delete.html'
|
||||||
permission_required = ('core.delete_child',)
|
permission_required = ('core.delete_child',)
|
||||||
success_url = '/children'
|
success_url = '/children'
|
||||||
|
|
||||||
|
|
||||||
class DiaperChangeList(PermissionRequiredMixin, FilterView):
|
class DiaperChangeList(PermissionRequiredMixin, FilterView):
|
||||||
model = DiaperChange
|
model = models.DiaperChange
|
||||||
template_name = 'core/diaperchange_list.html'
|
template_name = 'core/diaperchange_list.html'
|
||||||
permission_required = ('core.view_diaperchange',)
|
permission_required = ('core.view_diaperchange',)
|
||||||
paginate_by = 10
|
paginate_by = 10
|
||||||
|
@ -58,27 +69,27 @@ class DiaperChangeList(PermissionRequiredMixin, FilterView):
|
||||||
|
|
||||||
|
|
||||||
class DiaperChangeAdd(PermissionRequiredMixin, CreateView):
|
class DiaperChangeAdd(PermissionRequiredMixin, CreateView):
|
||||||
model = DiaperChange
|
model = models.DiaperChange
|
||||||
permission_required = ('core.add_diaperchange',)
|
permission_required = ('core.add_diaperchange',)
|
||||||
form_class = DiaperChangeForm
|
form_class = forms.DiaperChangeForm
|
||||||
success_url = '/changes'
|
success_url = '/changes'
|
||||||
|
|
||||||
|
|
||||||
class DiaperChangeUpdate(PermissionRequiredMixin, UpdateView):
|
class DiaperChangeUpdate(PermissionRequiredMixin, UpdateView):
|
||||||
model = DiaperChange
|
model = models.DiaperChange
|
||||||
permission_required = ('core.change_diaperchange',)
|
permission_required = ('core.change_diaperchange',)
|
||||||
form_class = DiaperChangeForm
|
form_class = forms.DiaperChangeForm
|
||||||
success_url = '/changes'
|
success_url = '/changes'
|
||||||
|
|
||||||
|
|
||||||
class DiaperChangeDelete(PermissionRequiredMixin, DeleteView):
|
class DiaperChangeDelete(PermissionRequiredMixin, DeleteView):
|
||||||
model = DiaperChange
|
model = models.DiaperChange
|
||||||
permission_required = ('core.delete_diaperchange',)
|
permission_required = ('core.delete_diaperchange',)
|
||||||
success_url = '/changes'
|
success_url = '/changes'
|
||||||
|
|
||||||
|
|
||||||
class FeedingList(PermissionRequiredMixin, FilterView):
|
class FeedingList(PermissionRequiredMixin, FilterView):
|
||||||
model = Feeding
|
model = models.Feeding
|
||||||
template_name = 'core/feeding_list.html'
|
template_name = 'core/feeding_list.html'
|
||||||
permission_required = ('core.view_feeding',)
|
permission_required = ('core.view_feeding',)
|
||||||
paginate_by = 10
|
paginate_by = 10
|
||||||
|
@ -86,9 +97,9 @@ class FeedingList(PermissionRequiredMixin, FilterView):
|
||||||
|
|
||||||
|
|
||||||
class FeedingAdd(PermissionRequiredMixin, CreateView):
|
class FeedingAdd(PermissionRequiredMixin, CreateView):
|
||||||
model = Feeding
|
model = models.Feeding
|
||||||
permission_required = ('core.add_feeding',)
|
permission_required = ('core.add_feeding',)
|
||||||
form_class = FeedingForm
|
form_class = forms.FeedingForm
|
||||||
success_url = '/feedings'
|
success_url = '/feedings'
|
||||||
|
|
||||||
def get_form_kwargs(self):
|
def get_form_kwargs(self):
|
||||||
|
@ -99,20 +110,20 @@ class FeedingAdd(PermissionRequiredMixin, CreateView):
|
||||||
|
|
||||||
|
|
||||||
class FeedingUpdate(PermissionRequiredMixin, UpdateView):
|
class FeedingUpdate(PermissionRequiredMixin, UpdateView):
|
||||||
model = Feeding
|
model = models.Feeding
|
||||||
permission_required = ('core.change_feeding',)
|
permission_required = ('core.change_feeding',)
|
||||||
form_class = FeedingForm
|
form_class = forms.FeedingForm
|
||||||
success_url = '/feedings'
|
success_url = '/feedings'
|
||||||
|
|
||||||
|
|
||||||
class FeedingDelete(PermissionRequiredMixin, DeleteView):
|
class FeedingDelete(PermissionRequiredMixin, DeleteView):
|
||||||
model = Feeding
|
model = models.Feeding
|
||||||
permission_required = ('core.delete_feeding',)
|
permission_required = ('core.delete_feeding',)
|
||||||
success_url = '/feedings'
|
success_url = '/feedings'
|
||||||
|
|
||||||
|
|
||||||
class NoteList(PermissionRequiredMixin, FilterView):
|
class NoteList(PermissionRequiredMixin, FilterView):
|
||||||
model = Note
|
model = models.Note
|
||||||
template_name = 'core/note_list.html'
|
template_name = 'core/note_list.html'
|
||||||
permission_required = ('core.view_note',)
|
permission_required = ('core.view_note',)
|
||||||
paginate_by = 10
|
paginate_by = 10
|
||||||
|
@ -120,27 +131,27 @@ class NoteList(PermissionRequiredMixin, FilterView):
|
||||||
|
|
||||||
|
|
||||||
class NoteAdd(PermissionRequiredMixin, CreateView):
|
class NoteAdd(PermissionRequiredMixin, CreateView):
|
||||||
model = Note
|
model = models.Note
|
||||||
permission_required = ('core.add_note',)
|
permission_required = ('core.add_note',)
|
||||||
fields = ['child', 'note']
|
fields = ['child', 'note']
|
||||||
success_url = '/notes'
|
success_url = '/notes'
|
||||||
|
|
||||||
|
|
||||||
class NoteUpdate(PermissionRequiredMixin, UpdateView):
|
class NoteUpdate(PermissionRequiredMixin, UpdateView):
|
||||||
model = Note
|
model = models.Note
|
||||||
permission_required = ('core.change_note',)
|
permission_required = ('core.change_note',)
|
||||||
fields = ['child', 'note']
|
fields = ['child', 'note']
|
||||||
success_url = '/notes'
|
success_url = '/notes'
|
||||||
|
|
||||||
|
|
||||||
class NoteDelete(PermissionRequiredMixin, DeleteView):
|
class NoteDelete(PermissionRequiredMixin, DeleteView):
|
||||||
model = Note
|
model = models.Note
|
||||||
permission_required = ('core.delete_note',)
|
permission_required = ('core.delete_note',)
|
||||||
success_url = '/notes'
|
success_url = '/notes'
|
||||||
|
|
||||||
|
|
||||||
class SleepList(PermissionRequiredMixin, FilterView):
|
class SleepList(PermissionRequiredMixin, FilterView):
|
||||||
model = Sleep
|
model = models.Sleep
|
||||||
template_name = 'core/sleep_list.html'
|
template_name = 'core/sleep_list.html'
|
||||||
permission_required = ('core.view_sleep',)
|
permission_required = ('core.view_sleep',)
|
||||||
paginate_by = 10
|
paginate_by = 10
|
||||||
|
@ -148,9 +159,9 @@ class SleepList(PermissionRequiredMixin, FilterView):
|
||||||
|
|
||||||
|
|
||||||
class SleepAdd(PermissionRequiredMixin, CreateView):
|
class SleepAdd(PermissionRequiredMixin, CreateView):
|
||||||
model = Sleep
|
model = models.Sleep
|
||||||
permission_required = ('core.add_sleep',)
|
permission_required = ('core.add_sleep',)
|
||||||
form_class = SleepForm
|
form_class = forms.SleepForm
|
||||||
success_url = '/sleep'
|
success_url = '/sleep'
|
||||||
|
|
||||||
def get_form_kwargs(self):
|
def get_form_kwargs(self):
|
||||||
|
@ -161,20 +172,20 @@ class SleepAdd(PermissionRequiredMixin, CreateView):
|
||||||
|
|
||||||
|
|
||||||
class SleepUpdate(PermissionRequiredMixin, UpdateView):
|
class SleepUpdate(PermissionRequiredMixin, UpdateView):
|
||||||
model = Sleep
|
model = models.Sleep
|
||||||
permission_required = ('core.change_sleep',)
|
permission_required = ('core.change_sleep',)
|
||||||
form_class = SleepForm
|
form_class = forms.SleepForm
|
||||||
success_url = '/sleep'
|
success_url = '/sleep'
|
||||||
|
|
||||||
|
|
||||||
class SleepDelete(PermissionRequiredMixin, DeleteView):
|
class SleepDelete(PermissionRequiredMixin, DeleteView):
|
||||||
model = Sleep
|
model = models.Sleep
|
||||||
permission_required = ('core.delete_sleep',)
|
permission_required = ('core.delete_sleep',)
|
||||||
success_url = '/sleep'
|
success_url = '/sleep'
|
||||||
|
|
||||||
|
|
||||||
class TimerList(PermissionRequiredMixin, FilterView):
|
class TimerList(PermissionRequiredMixin, FilterView):
|
||||||
model = Timer
|
model = models.Timer
|
||||||
template_name = 'core/timer_list.html'
|
template_name = 'core/timer_list.html'
|
||||||
permission_required = ('core.view_timer',)
|
permission_required = ('core.view_timer',)
|
||||||
paginate_by = 10
|
paginate_by = 10
|
||||||
|
@ -182,14 +193,14 @@ class TimerList(PermissionRequiredMixin, FilterView):
|
||||||
|
|
||||||
|
|
||||||
class TimerDetail(PermissionRequiredMixin, DetailView):
|
class TimerDetail(PermissionRequiredMixin, DetailView):
|
||||||
model = Timer
|
model = models.Timer
|
||||||
permission_required = ('core.view_timer',)
|
permission_required = ('core.view_timer',)
|
||||||
|
|
||||||
|
|
||||||
class TimerAdd(PermissionRequiredMixin, CreateView):
|
class TimerAdd(PermissionRequiredMixin, CreateView):
|
||||||
model = Timer
|
model = models.Timer
|
||||||
permission_required = ('core.add_timer',)
|
permission_required = ('core.add_timer',)
|
||||||
form_class = TimerForm
|
form_class = forms.TimerForm
|
||||||
success_url = '/timers'
|
success_url = '/timers'
|
||||||
|
|
||||||
def get_form_kwargs(self):
|
def get_form_kwargs(self):
|
||||||
|
@ -199,9 +210,9 @@ class TimerAdd(PermissionRequiredMixin, CreateView):
|
||||||
|
|
||||||
|
|
||||||
class TimerUpdate(PermissionRequiredMixin, UpdateView):
|
class TimerUpdate(PermissionRequiredMixin, UpdateView):
|
||||||
model = Timer
|
model = models.Timer
|
||||||
permission_required = ('core.change_timer',)
|
permission_required = ('core.change_timer',)
|
||||||
form_class = TimerForm
|
form_class = forms.TimerForm
|
||||||
success_url = '/timers'
|
success_url = '/timers'
|
||||||
|
|
||||||
def get_form_kwargs(self):
|
def get_form_kwargs(self):
|
||||||
|
@ -218,7 +229,7 @@ class TimerAddQuick(PermissionRequiredMixin, RedirectView):
|
||||||
permission_required = ('core.add_timer',)
|
permission_required = ('core.add_timer',)
|
||||||
|
|
||||||
def get(self, request, *args, **kwargs):
|
def get(self, request, *args, **kwargs):
|
||||||
instance = Timer.objects.create(user=request.user)
|
instance = models.Timer.objects.create(user=request.user)
|
||||||
instance.save()
|
instance.save()
|
||||||
self.url = request.GET.get(
|
self.url = request.GET.get(
|
||||||
'next', reverse('timer-detail', args={instance.id}))
|
'next', reverse('timer-detail', args={instance.id}))
|
||||||
|
@ -229,7 +240,7 @@ class TimerRestart(PermissionRequiredMixin, RedirectView):
|
||||||
permission_required = ('core.change_timer',)
|
permission_required = ('core.change_timer',)
|
||||||
|
|
||||||
def get(self, request, *args, **kwargs):
|
def get(self, request, *args, **kwargs):
|
||||||
instance = Timer.objects.get(id=kwargs['pk'])
|
instance = models.Timer.objects.get(id=kwargs['pk'])
|
||||||
instance.restart()
|
instance.restart()
|
||||||
return super(TimerRestart, self).get(request, *args, **kwargs)
|
return super(TimerRestart, self).get(request, *args, **kwargs)
|
||||||
|
|
||||||
|
@ -241,7 +252,7 @@ class TimerStop(PermissionRequiredMixin, RedirectView):
|
||||||
permission_required = ('core.change_timer',)
|
permission_required = ('core.change_timer',)
|
||||||
|
|
||||||
def get(self, request, *args, **kwargs):
|
def get(self, request, *args, **kwargs):
|
||||||
instance = Timer.objects.get(id=kwargs['pk'])
|
instance = models.Timer.objects.get(id=kwargs['pk'])
|
||||||
instance.stop()
|
instance.stop()
|
||||||
return super(TimerStop, self).get(request, *args, **kwargs)
|
return super(TimerStop, self).get(request, *args, **kwargs)
|
||||||
|
|
||||||
|
@ -250,13 +261,13 @@ class TimerStop(PermissionRequiredMixin, RedirectView):
|
||||||
|
|
||||||
|
|
||||||
class TimerDelete(PermissionRequiredMixin, DeleteView):
|
class TimerDelete(PermissionRequiredMixin, DeleteView):
|
||||||
model = Timer
|
model = models.Timer
|
||||||
permission_required = ('core.delete_timer',)
|
permission_required = ('core.delete_timer',)
|
||||||
success_url = '/'
|
success_url = '/'
|
||||||
|
|
||||||
|
|
||||||
class TummyTimeList(PermissionRequiredMixin, FilterView):
|
class TummyTimeList(PermissionRequiredMixin, FilterView):
|
||||||
model = TummyTime
|
model = models.TummyTime
|
||||||
template_name = 'core/tummytime_list.html'
|
template_name = 'core/tummytime_list.html'
|
||||||
permission_required = ('core.view_tummytime',)
|
permission_required = ('core.view_tummytime',)
|
||||||
paginate_by = 10
|
paginate_by = 10
|
||||||
|
@ -264,9 +275,9 @@ class TummyTimeList(PermissionRequiredMixin, FilterView):
|
||||||
|
|
||||||
|
|
||||||
class TummyTimeAdd(PermissionRequiredMixin, CreateView):
|
class TummyTimeAdd(PermissionRequiredMixin, CreateView):
|
||||||
model = TummyTime
|
model = models.TummyTime
|
||||||
permission_required = ('core.add_tummytime',)
|
permission_required = ('core.add_tummytime',)
|
||||||
form_class = TummyTimeForm
|
form_class = forms.TummyTimeForm
|
||||||
success_url = '/tummy-time'
|
success_url = '/tummy-time'
|
||||||
|
|
||||||
def get_form_kwargs(self):
|
def get_form_kwargs(self):
|
||||||
|
@ -277,13 +288,13 @@ class TummyTimeAdd(PermissionRequiredMixin, CreateView):
|
||||||
|
|
||||||
|
|
||||||
class TummyTimeUpdate(PermissionRequiredMixin, UpdateView):
|
class TummyTimeUpdate(PermissionRequiredMixin, UpdateView):
|
||||||
model = TummyTime
|
model = models.TummyTime
|
||||||
permission_required = ('core.change_tummytime',)
|
permission_required = ('core.change_tummytime',)
|
||||||
form_class = TummyTimeForm
|
form_class = forms.TummyTimeForm
|
||||||
success_url = '/tummy-time'
|
success_url = '/tummy-time'
|
||||||
|
|
||||||
|
|
||||||
class TummyTimeDelete(PermissionRequiredMixin, DeleteView):
|
class TummyTimeDelete(PermissionRequiredMixin, DeleteView):
|
||||||
model = TummyTime
|
model = models.TummyTime
|
||||||
permission_required = ('core.delete_tummytime',)
|
permission_required = ('core.delete_tummytime',)
|
||||||
success_url = '/tummy-time'
|
success_url = '/tummy-time'
|
||||||
|
|
|
@ -18,7 +18,6 @@
|
||||||
<a class="dropdown-item" href="{% url 'reports:report-diaperchange-lifetimes-child' object.slug %}">Diaper Lifetimes</a>
|
<a class="dropdown-item" href="{% url 'reports:report-diaperchange-lifetimes-child' object.slug %}">Diaper Lifetimes</a>
|
||||||
<a class="dropdown-item" href="{% url 'reports:report-sleep-pattern-child' object.slug %}">Sleep Pattern</a>
|
<a class="dropdown-item" href="{% url 'reports:report-sleep-pattern-child' object.slug %}">Sleep Pattern</a>
|
||||||
<a class="dropdown-item" href="{% url 'reports:report-sleep-totals-child' object.slug %}">Sleep Totals</a>
|
<a class="dropdown-item" href="{% url 'reports:report-sleep-totals-child' object.slug %}">Sleep Totals</a>
|
||||||
<a class="dropdown-item" href="{% url 'reports:report-timeline-child' object.slug %}">Timeline</a>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
@ -2,4 +2,3 @@ from .diaperchange_lifetimes import diaperchange_lifetimes # NOQA
|
||||||
from .diaperchange_types import diaperchange_types # NOQA
|
from .diaperchange_types import diaperchange_types # NOQA
|
||||||
from .sleep_pattern import sleep_pattern # NOQA
|
from .sleep_pattern import sleep_pattern # NOQA
|
||||||
from .sleep_totals import sleep_totals # NOQA
|
from .sleep_totals import sleep_totals # NOQA
|
||||||
from .timeline import timeline # NOQA
|
|
||||||
|
|
|
@ -1,42 +0,0 @@
|
||||||
{% extends 'reports/report_base.html' %}
|
|
||||||
{% load static %}
|
|
||||||
|
|
||||||
{% block title %}Timeline - {{ object }}{% endblock %}
|
|
||||||
|
|
||||||
{% block breadcrumbs %}
|
|
||||||
{{ block.super }}
|
|
||||||
<li class="breadcrumb-item active" aria-current="page">Timeline</li>
|
|
||||||
{% endblock %}
|
|
||||||
|
|
||||||
{% block content %}
|
|
||||||
<h1 class="text-center">Timeline</h1>
|
|
||||||
<h2 class="text-center text-muted">{{ object }}</h2>
|
|
||||||
<h3 class="text-center">
|
|
||||||
<a class="btn btn-sm btn-default" href="?date={{ date_previous|date:"Y-m-d" }}" aria-label="Previous">
|
|
||||||
<i class="icon icon-chevron-left" aria-hidden="true"></i>
|
|
||||||
<span class="sr-only">Previous</span>
|
|
||||||
</a>
|
|
||||||
{{ date|date }}
|
|
||||||
<a class="btn btn-sm btn-default" href="?date={{ date_next|date:"Y-m-d" }}" aria-label="Next">
|
|
||||||
<i class="icon icon-chevron-right" aria-hidden="true"></i>
|
|
||||||
<span class="sr-only">Next</span>
|
|
||||||
</a>
|
|
||||||
</h3>
|
|
||||||
<ul class="timeline m-auto">
|
|
||||||
{% for object in objects %}
|
|
||||||
<li{% cycle "" ' class="timeline-inverted"' %}>
|
|
||||||
<div class="timeline-badge {% if object.type == "start" %}bg-success{% elif object.type == "end" %}bg-danger{% else %}bg-info{% endif %}">
|
|
||||||
<i class="icon icon-{{ object.model_name }}"></i>
|
|
||||||
</div>
|
|
||||||
<div class="card text-right">
|
|
||||||
<div class="card-body">
|
|
||||||
{{ object.event }}
|
|
||||||
</div>
|
|
||||||
<div class="card-footer text-muted">
|
|
||||||
{{ object.time|timesince }} ago ({{ object.time|time }})
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</li>
|
|
||||||
{% endfor %}
|
|
||||||
</ul>
|
|
||||||
{% endblock %}
|
|
|
@ -44,6 +44,3 @@ class ViewsTestCase(TestCase):
|
||||||
self.assertEqual(page.status_code, 200)
|
self.assertEqual(page.status_code, 200)
|
||||||
page = self.c.get('{}/sleep/totals/'.format(base_url))
|
page = self.c.get('{}/sleep/totals/'.format(base_url))
|
||||||
self.assertEqual(page.status_code, 200)
|
self.assertEqual(page.status_code, 200)
|
||||||
|
|
||||||
page = self.c.get('{}/timeline/'.format(base_url))
|
|
||||||
self.assertEqual(page.status_code, 200)
|
|
||||||
|
|
|
@ -19,8 +19,4 @@ urlpatterns = [
|
||||||
url(r'^children/(?P<slug>[^/.]+)/reports/sleep/totals/$',
|
url(r'^children/(?P<slug>[^/.]+)/reports/sleep/totals/$',
|
||||||
views.SleepTotalsChildReport.as_view(),
|
views.SleepTotalsChildReport.as_view(),
|
||||||
name='report-sleep-totals-child'),
|
name='report-sleep-totals-child'),
|
||||||
|
|
||||||
url(r'^children/(?P<slug>[^/.]+)/reports/timeline/$',
|
|
||||||
views.TimelineChildReport.as_view(),
|
|
||||||
name='report-timeline-child'),
|
|
||||||
]
|
]
|
||||||
|
|
|
@ -3,12 +3,11 @@ from __future__ import unicode_literals
|
||||||
|
|
||||||
from django.contrib.auth.mixins import PermissionRequiredMixin
|
from django.contrib.auth.mixins import PermissionRequiredMixin
|
||||||
from django.views.generic.detail import DetailView
|
from django.views.generic.detail import DetailView
|
||||||
from django.utils import timezone
|
|
||||||
|
|
||||||
from core.models import Child, DiaperChange, Sleep
|
from core.models import Child, DiaperChange, Sleep
|
||||||
|
|
||||||
from .graphs import (diaperchange_types, diaperchange_lifetimes, sleep_pattern,
|
from .graphs import (diaperchange_types, diaperchange_lifetimes, sleep_pattern,
|
||||||
sleep_totals, timeline)
|
sleep_totals)
|
||||||
|
|
||||||
|
|
||||||
class DiaperChangeLifetimesChildReport(PermissionRequiredMixin, DetailView):
|
class DiaperChangeLifetimesChildReport(PermissionRequiredMixin, DetailView):
|
||||||
|
@ -89,22 +88,3 @@ class SleepTotalsChildReport(PermissionRequiredMixin, DetailView):
|
||||||
if instances:
|
if instances:
|
||||||
context['html'], context['javascript'] = sleep_totals(instances)
|
context['html'], context['javascript'] = sleep_totals(instances)
|
||||||
return context
|
return context
|
||||||
|
|
||||||
|
|
||||||
class TimelineChildReport(PermissionRequiredMixin, DetailView):
|
|
||||||
"""Chronological daily view of events (non-graph).
|
|
||||||
"""
|
|
||||||
model = Child
|
|
||||||
permission_required = ('core.view_child',)
|
|
||||||
template_name = 'reports/timeline.html'
|
|
||||||
|
|
||||||
def get_context_data(self, **kwargs):
|
|
||||||
context = super(TimelineChildReport, self).get_context_data(**kwargs)
|
|
||||||
date = self.request.GET.get('date', str(timezone.localdate()))
|
|
||||||
date = timezone.datetime.strptime(date, '%Y-%m-%d')
|
|
||||||
date = timezone.localtime(timezone.make_aware(date))
|
|
||||||
context['objects'] = timeline(self.object, date)
|
|
||||||
context['date'] = date
|
|
||||||
context['date_previous'] = date - timezone.timedelta(days=1)
|
|
||||||
context['date_next'] = date + timezone.timedelta(days=1)
|
|
||||||
return context
|
|
||||||
|
|
Loading…
Reference in New Issue