mirror of https://github.com/snachodog/mybuddy.git
Dashboard: Hide old data (#215)
* filter card data by age * add setting for hide_age * add option to settings form * fix name to consistently use hide_age * rename filter, use setting for filter * add test for old hiding old data * fix migration to contain correct imports, remove month from timedelta * remove months from timedelta, allow blank * fix with block * add settings test * add test for filter * mock localtime * fix timezone issues with tests * linting * linting * Adjust migration Co-authored-by: Benjamin Häublein <benjaminh@debian.vm.hp> Co-authored-by: Christopher C. Wells <git@chris-wells.net>
This commit is contained in:
parent
c3dc4520fc
commit
e8696a8b00
|
@ -14,7 +14,10 @@ class SettingsInline(admin.StackedInline):
|
|||
can_delete = False
|
||||
fieldsets = (
|
||||
(_('Dashboard'), {
|
||||
'fields': ('dashboard_refresh_rate', 'dashboard_hide_empty',)
|
||||
'fields': (
|
||||
'dashboard_refresh_rate',
|
||||
'dashboard_hide_empty',
|
||||
'dashboard_hide_age')
|
||||
}),
|
||||
)
|
||||
|
||||
|
|
|
@ -44,6 +44,7 @@ class UserSettingsForm(forms.ModelForm):
|
|||
fields = [
|
||||
'dashboard_refresh_rate',
|
||||
'dashboard_hide_empty',
|
||||
'dashboard_hide_age',
|
||||
'language',
|
||||
'timezone'
|
||||
]
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
from django.db import migrations, models
|
||||
from django.utils import timezone
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('babybuddy', '0016_alter_settings_timezone'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='settings',
|
||||
name='dashboard_hide_age',
|
||||
field=models.DurationField(
|
||||
choices=[
|
||||
(None, 'show all data'),
|
||||
(timezone.timedelta(days=1), '1 day'),
|
||||
(timezone.timedelta(days=2), '2 days'),
|
||||
(timezone.timedelta(days=3), '3 days'),
|
||||
(timezone.timedelta(weeks=1), '1 week'),
|
||||
(timezone.timedelta(weeks=4), '4 weeks')
|
||||
],
|
||||
default=None,
|
||||
null=True,
|
||||
verbose_name='Hide data older than'),
|
||||
),
|
||||
]
|
|
@ -39,6 +39,21 @@ class Settings(models.Model):
|
|||
default=False,
|
||||
editable=True
|
||||
)
|
||||
dashboard_hide_age = models.DurationField(
|
||||
verbose_name=_('Hide data older than'),
|
||||
help_text=_('This setting controls which data will be shown '
|
||||
'in the dashboard.'),
|
||||
blank=True,
|
||||
null=True,
|
||||
default=None,
|
||||
choices=[
|
||||
(None, _('show all data')),
|
||||
(timezone.timedelta(days=1), _('1 day')),
|
||||
(timezone.timedelta(days=2), _('2 days')),
|
||||
(timezone.timedelta(days=3), _('3 days')),
|
||||
(timezone.timedelta(weeks=1), _('1 week')),
|
||||
(timezone.timedelta(weeks=4), _('4 weeks')),
|
||||
])
|
||||
language = models.CharField(
|
||||
choices=settings.LANGUAGES,
|
||||
default=settings.LANGUAGE_CODE,
|
||||
|
|
|
@ -69,6 +69,11 @@
|
|||
{% include 'babybuddy/form_field.html' %}
|
||||
{% endwith %}
|
||||
</div>
|
||||
<div class="form-group row">
|
||||
{% with form_settings.dashboard_hide_age as field %}
|
||||
{% include 'babybuddy/form_field.html' %}
|
||||
{% endwith %}
|
||||
</div>
|
||||
</fieldset>
|
||||
<fieldset>
|
||||
<legend>{% trans "API" %}</legend>
|
||||
|
|
|
@ -157,3 +157,15 @@ class FormsTestCase(TestCase):
|
|||
self.user.refresh_from_db()
|
||||
self.assertEqual(self.user.settings.dashboard_refresh_rate,
|
||||
datetime.timedelta(seconds=300))
|
||||
|
||||
def test_user_settings_dashboard_hide_age(self):
|
||||
self.c.login(**self.credentials)
|
||||
|
||||
params = self.settings_template.copy()
|
||||
params['dashboard_hide_age'] = '1 day, 0:00:00'
|
||||
|
||||
page = self.c.post('/user/settings/', data=params, follow=True)
|
||||
self.assertEqual(page.status_code, 200)
|
||||
self.user.refresh_from_db()
|
||||
self.assertEqual(self.user.settings.dashboard_hide_age,
|
||||
datetime.timedelta(days=1))
|
||||
|
|
|
@ -16,6 +16,15 @@ def _hide_empty(context):
|
|||
return context['request'].user.settings.dashboard_hide_empty
|
||||
|
||||
|
||||
def _filter_data_age(context, keyword="end"):
|
||||
filter = {}
|
||||
if context['request'].user.settings.dashboard_hide_age:
|
||||
now = timezone.localtime()
|
||||
start_time = now - context['request'].user.settings.dashboard_hide_age
|
||||
filter[keyword + "__range"] = (start_time, now)
|
||||
return filter
|
||||
|
||||
|
||||
@register.inclusion_tag('cards/diaperchange_last.html', takes_context=True)
|
||||
def card_diaperchange_last(context, child):
|
||||
"""
|
||||
|
@ -23,8 +32,9 @@ def card_diaperchange_last(context, child):
|
|||
:param child: an instance of the Child model.
|
||||
:returns: a dictionary with the most recent Diaper Change instance.
|
||||
"""
|
||||
instance = models.DiaperChange.objects.filter(
|
||||
child=child).order_by('-time').first()
|
||||
instance = models.DiaperChange.objects.filter(child=child) \
|
||||
.filter(**_filter_data_age(context, "time")) \
|
||||
.order_by('-time').first()
|
||||
empty = not instance
|
||||
|
||||
return {
|
||||
|
@ -127,6 +137,7 @@ def card_feeding_last(context, child):
|
|||
:returns: a dictionary with the most recent Feeding instance.
|
||||
"""
|
||||
instance = models.Feeding.objects.filter(child=child) \
|
||||
.filter(**_filter_data_age(context)) \
|
||||
.order_by('-end').first()
|
||||
empty = not instance
|
||||
|
||||
|
@ -146,6 +157,7 @@ def card_feeding_last_method(context, child):
|
|||
:returns: a dictionary with the most recent Feeding instances.
|
||||
"""
|
||||
instances = models.Feeding.objects.filter(child=child) \
|
||||
.filter(**_filter_data_age(context)) \
|
||||
.order_by('-end')[:3]
|
||||
empty = len(instances) == 0
|
||||
|
||||
|
@ -166,6 +178,7 @@ def card_sleep_last(context, child):
|
|||
:returns: a dictionary with the most recent Sleep instance.
|
||||
"""
|
||||
instance = models.Sleep.objects.filter(child=child) \
|
||||
.filter(**_filter_data_age(context)) \
|
||||
.order_by('-end').first()
|
||||
empty = not instance
|
||||
|
||||
|
@ -496,6 +509,7 @@ def card_tummytime_last(context, child):
|
|||
:returns: a dictionary with the most recent Tummy Time instance.
|
||||
"""
|
||||
instance = models.TummyTime.objects.filter(child=child) \
|
||||
.filter(**_filter_data_age(context)) \
|
||||
.order_by('-end').first()
|
||||
empty = not instance
|
||||
|
||||
|
|
|
@ -9,6 +9,8 @@ from babybuddy.models import Settings
|
|||
from core import models
|
||||
from dashboard.templatetags import cards
|
||||
|
||||
from unittest import mock
|
||||
|
||||
|
||||
class MockUserRequest:
|
||||
def __init__(self, user):
|
||||
|
@ -39,6 +41,31 @@ class TemplateTagsTestCase(TestCase):
|
|||
hide_empty = cards._hide_empty(context)
|
||||
self.assertTrue(hide_empty)
|
||||
|
||||
def test_filter_data_age_none(self):
|
||||
request = MockUserRequest(User.objects.first())
|
||||
request.user.settings.dashboard_hide_age = None
|
||||
context = {'request': request}
|
||||
filter_data_age = cards._filter_data_age(context)
|
||||
self.assertFalse(len(filter_data_age))
|
||||
|
||||
@mock.patch('dashboard.templatetags.cards.timezone')
|
||||
def test_filter_data_age_one_day(self, mocked_timezone):
|
||||
request = MockUserRequest(User.objects.first())
|
||||
request.user.settings.dashboard_hide_age = timezone.timedelta(days=1)
|
||||
context = {'request': request}
|
||||
mocked_timezone.localtime.return_value = \
|
||||
timezone.localtime().strptime('2017-11-18', '%Y-%m-%d')
|
||||
|
||||
filter_data_age = cards._filter_data_age(context, keyword="time")
|
||||
|
||||
self.assertIn("time__range", filter_data_age)
|
||||
self.assertEqual(
|
||||
filter_data_age["time__range"][0],
|
||||
timezone.localtime().strptime('2017-11-17', '%Y-%m-%d'))
|
||||
self.assertEqual(
|
||||
filter_data_age["time__range"][1],
|
||||
timezone.localtime().strptime('2017-11-18', '%Y-%m-%d'))
|
||||
|
||||
def test_card_diaperchange_last(self):
|
||||
data = cards.card_diaperchange_last(self.context, self.child)
|
||||
self.assertEqual(data['type'], 'diaperchange')
|
||||
|
@ -47,6 +74,17 @@ class TemplateTagsTestCase(TestCase):
|
|||
self.assertIsInstance(data['change'], models.DiaperChange)
|
||||
self.assertEqual(data['change'], models.DiaperChange.objects.first())
|
||||
|
||||
@mock.patch('dashboard.templatetags.cards.timezone')
|
||||
def test_card_diaperchange_last_filter_age(self, mocked_timezone):
|
||||
request = MockUserRequest(User.objects.first())
|
||||
request.user.settings.dashboard_hide_age = timezone.timedelta(days=1)
|
||||
context = {'request': request}
|
||||
time = timezone.localtime().strptime('2017-11-10', '%Y-%m-%d')
|
||||
mocked_timezone.localtime.return_value = timezone.make_aware(time)
|
||||
|
||||
data = cards.card_diaperchange_last(context, self.child)
|
||||
self.assertTrue(data['empty'])
|
||||
|
||||
def test_card_diaperchange_types(self):
|
||||
data = cards.card_diaperchange_types(
|
||||
self.context,
|
||||
|
|
Loading…
Reference in New Issue