mirror of https://github.com/snachodog/mybuddy.git
Populate the all-children timeline
This commit is contained in:
parent
0990678325
commit
10af931279
|
@ -29,77 +29,7 @@
|
|||
</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="{% trans "Previous" %}">
|
||||
<i class="icon icon-chevron-left" aria-hidden="true"></i>
|
||||
<span class="sr-only">{% trans "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="{% trans "Next" %}">
|
||||
<i class="icon icon-chevron-right" aria-hidden="true"></i>
|
||||
<span class="sr-only">{% trans "Next" %}</span>
|
||||
</a>
|
||||
{% endif %}
|
||||
</h3>
|
||||
{% if timeline_objects %}
|
||||
<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 }}
|
||||
{% for detail in object.details %}
|
||||
<div><small>{{ detail }}</small></div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
<div class="card-footer text-muted">
|
||||
{% blocktrans trimmed with since=object.time|timesince time=object.time|time %}
|
||||
{{ since }} ago ({{ time }})
|
||||
{% endblocktrans %}
|
||||
{% if object.duration %}
|
||||
<div>
|
||||
<small>Duration: {{ object.duration }}</small>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% if object.time_since_prev %}
|
||||
<div>
|
||||
<small>{{ object.time_since_prev }} since previous</small>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% if object.edit_link %}
|
||||
<div>
|
||||
<small><a href="{{ object.edit_link }}">Edit</a></small>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
<h3 class="text-center">
|
||||
{% if date_previous %}
|
||||
<a class="btn btn-sm btn-default" href="?date={{ date_previous|date:"Y-m-d" }}" aria-label="{% trans "Previous" %}">
|
||||
<i class="icon icon-chevron-left" aria-hidden="true"></i>
|
||||
<span class="sr-only">{% trans "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="{% trans "Next" %}">
|
||||
<i class="icon icon-chevron-right" aria-hidden="true"></i>
|
||||
<span class="sr-only">{% trans "Next" %}</span>
|
||||
</a>
|
||||
{% endif %}
|
||||
</h3>
|
||||
{% else %}
|
||||
<div class="text-center">No events</div>
|
||||
{% endif %}
|
||||
{% include 'timeline/_timeline.html' %}
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
|
|
@ -0,0 +1,73 @@
|
|||
{% load i18n %}
|
||||
|
||||
<h3 class="text-center">
|
||||
{% if date_previous %}
|
||||
<a class="btn btn-sm btn-default" href="?date={{ date_previous|date:"Y-m-d" }}" aria-label="{% trans "Previous" %}">
|
||||
<i class="icon icon-chevron-left" aria-hidden="true"></i>
|
||||
<span class="sr-only">{% trans "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="{% trans "Next" %}">
|
||||
<i class="icon icon-chevron-right" aria-hidden="true"></i>
|
||||
<span class="sr-only">{% trans "Next" %}</span>
|
||||
</a>
|
||||
{% endif %}
|
||||
</h3>
|
||||
{% if timeline_objects %}
|
||||
<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 }}
|
||||
{% for detail in object.details %}
|
||||
<div><small>{{ detail }}</small></div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
<div class="card-footer text-muted">
|
||||
{% blocktrans trimmed with since=object.time|timesince time=object.time|time %}
|
||||
{{ since }} ago ({{ time }})
|
||||
{% endblocktrans %}
|
||||
{% if object.duration %}
|
||||
<div>
|
||||
<small>Duration: {{ object.duration }}</small>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% if object.time_since_prev %}
|
||||
<div>
|
||||
<small>{{ object.time_since_prev }} since previous</small>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% if object.edit_link %}
|
||||
<div>
|
||||
<small><a href="{{ object.edit_link }}">Edit</a></small>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
<h3 class="text-center">
|
||||
{% if date_previous %}
|
||||
<a class="btn btn-sm btn-default" href="?date={{ date_previous|date:"Y-m-d" }}" aria-label="{% trans "Previous" %}">
|
||||
<i class="icon icon-chevron-left" aria-hidden="true"></i>
|
||||
<span class="sr-only">{% trans "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="{% trans "Next" %}">
|
||||
<i class="icon icon-chevron-right" aria-hidden="true"></i>
|
||||
<span class="sr-only">{% trans "Next" %}</span>
|
||||
</a>
|
||||
{% endif %}
|
||||
</h3>
|
||||
{% else %}
|
||||
<div class="text-center">No events</div>
|
||||
{% endif %}
|
|
@ -8,5 +8,9 @@
|
|||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
{# TODO! #}
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
{% include 'timeline/_timeline.html' %}
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
|
|
@ -7,30 +7,32 @@ from core.models import DiaperChange, Feeding, Sleep, TummyTime
|
|||
from datetime import timedelta
|
||||
|
||||
|
||||
def get_objects(child, date):
|
||||
def get_objects(date, child=None):
|
||||
"""
|
||||
Create a time-sorted dictionary of all events for a child.
|
||||
:param child: an instance of a Child.
|
||||
:param date: a DateTime instance for the day to be summarized.
|
||||
:param child: Child instance to filter results for (no filter if `None`).
|
||||
:returns: a list of the day's events.
|
||||
"""
|
||||
min_date = date
|
||||
max_date = date.replace(hour=23, minute=59, second=59)
|
||||
events = []
|
||||
|
||||
_add_diaper_changes(child, min_date, max_date, events)
|
||||
_add_feedings(child, min_date, max_date, events)
|
||||
_add_sleeps(child, min_date, max_date, events)
|
||||
_add_tummy_times(child, min_date, max_date, events)
|
||||
_add_diaper_changes(min_date, max_date, events, child)
|
||||
_add_feedings(min_date, max_date, events, child)
|
||||
_add_sleeps(min_date, max_date, events, child)
|
||||
_add_tummy_times(min_date, max_date, events, child)
|
||||
|
||||
events.sort(key=lambda x: x['time'], reverse=True)
|
||||
|
||||
return events
|
||||
|
||||
|
||||
def _add_tummy_times(child, min_date, max_date, events):
|
||||
instances = TummyTime.objects.filter(child=child).filter(
|
||||
def _add_tummy_times(min_date, max_date, events, child=None):
|
||||
instances = TummyTime.objects.filter(
|
||||
start__range=(min_date, max_date)).order_by('-start')
|
||||
if child:
|
||||
instances = instances.filter(child=child)
|
||||
for instance in instances:
|
||||
details = []
|
||||
if instance.milestone:
|
||||
|
@ -59,9 +61,11 @@ def _add_tummy_times(child, min_date, max_date, events):
|
|||
})
|
||||
|
||||
|
||||
def _add_sleeps(child, min_date, max_date, events):
|
||||
instances = Sleep.objects.filter(child=child).filter(
|
||||
def _add_sleeps(min_date, max_date, events, child=None):
|
||||
instances = Sleep.objects.filter(
|
||||
start__range=(min_date, max_date)).order_by('-start')
|
||||
if child:
|
||||
instances = instances.filter(child=child)
|
||||
for instance in instances:
|
||||
details = []
|
||||
if instance.notes:
|
||||
|
@ -90,12 +94,15 @@ def _add_sleeps(child, min_date, max_date, events):
|
|||
})
|
||||
|
||||
|
||||
def _add_feedings(child, min_date, max_date, events):
|
||||
yesterday = min_date - timedelta(days=1) # So first feeding has a previous
|
||||
def _add_feedings(min_date, max_date, events, child=None):
|
||||
# Ensure first feeding has a previous.
|
||||
yesterday = min_date - timedelta(days=1)
|
||||
prev_start = None
|
||||
|
||||
instances = Feeding.objects.filter(child=child).filter(
|
||||
instances = Feeding.objects.filter(
|
||||
start__range=(yesterday, max_date)).order_by('start')
|
||||
if child:
|
||||
instances = instances.filter(child=child)
|
||||
for instance in instances:
|
||||
details = []
|
||||
if instance.notes:
|
||||
|
@ -136,9 +143,11 @@ def _add_feedings(child, min_date, max_date, events):
|
|||
})
|
||||
|
||||
|
||||
def _add_diaper_changes(child, min_date, max_date, events):
|
||||
instances = DiaperChange.objects.filter(child=child).filter(
|
||||
def _add_diaper_changes(min_date, max_date, events, child):
|
||||
instances = DiaperChange.objects.filter(
|
||||
time__range=(min_date, max_date)).order_by('-time')
|
||||
if child:
|
||||
instances = instances.filter(child=child)
|
||||
for instance in instances:
|
||||
contents = []
|
||||
if instance.wet:
|
||||
|
@ -153,7 +162,7 @@ def _add_diaper_changes(child, min_date, max_date, events):
|
|||
events.append({
|
||||
'time': timezone.localtime(instance.time),
|
||||
'event': _('%(child)s had a diaper change.') % {
|
||||
'child': child.first_name
|
||||
'child': instance.child.first_name
|
||||
},
|
||||
'details': details,
|
||||
'edit_link': reverse('core:diaperchange-update',
|
||||
|
|
|
@ -17,6 +17,17 @@ from babybuddy.views import BabyBuddyFilterView
|
|||
from core import forms, models, timeline
|
||||
|
||||
|
||||
def _prepare_timeline_context_data(context, date, child=None):
|
||||
date = timezone.datetime.strptime(date, '%Y-%m-%d')
|
||||
date = timezone.localtime(timezone.make_aware(date))
|
||||
context['timeline_objects'] = timeline.get_objects(date, child)
|
||||
context['date'] = date
|
||||
context['date_previous'] = date - timezone.timedelta(days=1)
|
||||
if date.date() < timezone.localdate():
|
||||
context['date_next'] = date + timezone.timedelta(days=1)
|
||||
pass
|
||||
|
||||
|
||||
class CoreAddView(PermissionRequired403Mixin, SuccessMessageMixin, CreateView):
|
||||
def get_success_message(self, cleaned_data):
|
||||
cleaned_data['model'] = self.model._meta.verbose_name.title()
|
||||
|
@ -92,13 +103,7 @@ class ChildDetail(PermissionRequired403Mixin, DetailView):
|
|||
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)
|
||||
_prepare_timeline_context_data(context, date, self.object)
|
||||
return context
|
||||
|
||||
|
||||
|
@ -284,8 +289,8 @@ class Timeline(LoginRequiredMixin, TemplateView):
|
|||
|
||||
def get_context_data(self, **kwargs):
|
||||
context = super(Timeline, self).get_context_data(**kwargs)
|
||||
# TODO: Get relevant data for a given day.
|
||||
context['objects'] = models.Child.objects.all()
|
||||
date = self.request.GET.get('date', str(timezone.localdate()))
|
||||
_prepare_timeline_context_data(context, date)
|
||||
return context
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue