Skip to content

Commit 0e25f5d

Browse files
authored
feat: Event Archive (#90)
* WIP: event archive pages * WIP: add observation_event_meta.html template * WIP: Update event models with situation field * feat: Restrict observation quote to one line * feat: Add event templates for ObservationMade and ObservationClosed * fix: Remove add_published
1 parent 6d29053 commit 0e25f5d

19 files changed

+320
-62
lines changed

DECISION.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# Decision tree
2+
3+
## If I want to listen for keyboard shortcuts in Vue
4+
5+
Use [GlobalEvents](https://github.com/shentao/vue-global-events/tree/v1).

PROD.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
2+
3+
4+
5+
The following code is used to find and display instances where there are multiple ObservationUpdated entries with the same published date and observation_id, but only when the published time is not exactly midnight. This could be useful for identifying potential data inconsistencies or duplicate entries in the database.
6+
7+
```python
8+
k = ObservationUpdated.objects.values('published', 'observation_id').annotate(cnt=Count('published')).order_by()
9+
t = list(filter(lambda x: x['cnt'] > 1, k))
10+
u = list(filter(lambda x: x['published'].hour != 0 and x['published'].minute != 0, t))
11+
for i in u:
12+
print(i)
13+
14+
```

TODO.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,8 @@
5757
- [ ] Implement $ on tasks, so that only part of information is shown on the task list, all can be edited
5858
- [x] Add a Journal archive view set
5959
- [ ] Add an event archive view set
60-
- [ ] Remove add_published from templatetags
60+
- [x] Remove add_published from templatetags
61+
- [ ] Check #253 – is ObservationMade done here?
6162
- [x] Add a special symbol in journal to add a line to a reflection
6263
- Symbols: [x] [~] [^]
6364
- How about [ ] for Plan?

tasks/apps/tree/models.py

Lines changed: 35 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,8 @@ class HabitTracked(Event):
146146

147147
note = models.TextField(null=True, blank=True)
148148

149+
template = "tree/events/habit_tracked.html"
150+
149151
def __str__(self):
150152
return "{} {}".format(self.habit, self.published)
151153

@@ -258,12 +260,30 @@ def copy(self, as_new=True):
258260
def coalesce(value, default=''):
259261
return value if value is not None else default
260262

261-
class ObservationEventMixin:
263+
class ObservationPropertyEventMixin:
262264
@property
263265
def observation(self):
264266
return Observation.objects.get(event_stream_id=self.event_stream_id)
265267

266-
class ObservationMade(Event, ObservationEventMixin):
268+
class ObservationEventMixin:
269+
def situation(self):
270+
### XXX Situation at the time of the event or current?
271+
### For now, current is implemented here
272+
event = Event.objects.instance_of(
273+
ObservationMade,
274+
ObservationRecontextualized
275+
).filter(
276+
event_stream_id=self.event_stream_id
277+
).order_by(
278+
'-published'
279+
).first()
280+
281+
if not event:
282+
raise Observation.DoesNotExist
283+
284+
return event.situation
285+
286+
class ObservationMade(Event, ObservationEventMixin, ObservationPropertyEventMixin):
267287
# event_stream_id <- Observation
268288
# thread <- Observation (can be updated)
269289

@@ -273,6 +293,8 @@ class ObservationMade(Event, ObservationEventMixin):
273293
interpretation = models.TextField(help_text=_("How you saw it, what you felt?"), null=True, blank=True)
274294
approach = models.TextField(help_text=_("How should you approach it in the future?"), null=True, blank=True)
275295

296+
template = "tree/events/observation_made.html"
297+
276298
@staticmethod
277299
def from_observation(observation, published=None):
278300
return ObservationMade(
@@ -292,21 +314,21 @@ def __str__(self):
292314
self.thread
293315
)
294316

295-
class ObservationUpdated(Event):
317+
class ObservationUpdated(Event, ObservationEventMixin):
296318
observation = models.ForeignKey(Observation, on_delete=models.SET_NULL, null=True, blank=True)
297319

298-
### TODO add template
320+
template = "tree/events/observation_updated.html"
299321

300322
comment = models.TextField(help_text=_("Update"))
301323

302324
def __str__(self):
303325
return self.comment
304326

305-
class ObservationRecontextualized(Event, ObservationEventMixin):
327+
class ObservationRecontextualized(Event, ObservationEventMixin, ObservationPropertyEventMixin):
306328
old_situation = models.TextField(blank=True)
307329
situation = models.TextField()
308330

309-
### TODO add template
331+
template = "tree/events/observation_recontextualized.html"
310332

311333
@staticmethod
312334
def from_observation(observation, old, published=None):
@@ -318,7 +340,7 @@ def from_observation(observation, old, published=None):
318340
situation=coalesce(observation.situation),
319341
)
320342

321-
class ObservationReinterpreted(Event, ObservationEventMixin):
343+
class ObservationReinterpreted(Event, ObservationEventMixin, ObservationPropertyEventMixin):
322344
old_interpretation = models.TextField(blank=True)
323345
interpretation = models.TextField()
324346

@@ -334,11 +356,11 @@ def from_observation(observation, old, published=None):
334356
interpretation=coalesce(observation.interpretation),
335357
)
336358

337-
class ObservationReflectedUpon(Event, ObservationEventMixin):
359+
class ObservationReflectedUpon(Event, ObservationEventMixin, ObservationPropertyEventMixin):
338360
old_approach = models.TextField(blank=True)
339361
approach = models.TextField()
340362

341-
### TODO add template
363+
template = "tree/events/observation_reflectedupon.html"
342364

343365
@staticmethod
344366
def from_observation(observation, old, published=None):
@@ -350,14 +372,14 @@ def from_observation(observation, old, published=None):
350372
approach=coalesce(observation.approach),
351373
)
352374

353-
class ObservationClosed(Event, ObservationEventMixin):
375+
class ObservationClosed(Event, ObservationEventMixin, ObservationPropertyEventMixin):
354376
type = models.ForeignKey(ObservationType, on_delete=models.CASCADE)
355377

356378
situation = models.TextField(help_text=_("What happened?"), null=True, blank=True)
357379
interpretation = models.TextField(help_text=_("How you saw it, what you felt?"), null=True, blank=True)
358380
approach = models.TextField(help_text=_("How should you approach it in the future?"), null=True, blank=True)
359381

360-
### TODO add template
382+
template = "tree/events/observation_closed.html"
361383

362384
@staticmethod
363385
def from_observation(observation, published=None):
@@ -410,6 +432,8 @@ def on_observation_thread_change_update_events(sender, instance, *args, **kwargs
410432
class JournalAdded(Event):
411433
comment = models.TextField(help_text=_("Update"))
412434

435+
template = "tree/events/journal_added.html"
436+
413437
def __str__(self):
414438
return self.comment
415439

tasks/apps/tree/templatetags/model_presenters.py

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,18 @@
22

33
from django.template.defaultfilters import linebreaks
44
from django.utils.safestring import mark_safe
5+
from django.template.defaultfilters import stringfilter
56

67

78
register = template.Library()
89

910

1011
@register.filter
11-
def add_published(object):
12-
linebreaks_str = linebreaks(object.comment)
13-
14-
time_str = '<p data-time="{}">'.format(
15-
object.published.strftime('%H:%M')
16-
)
17-
18-
return mark_safe(linebreaks_str.replace('<p>', time_str, 1))
12+
@stringfilter
13+
def first_line(text):
14+
splitted = text.split('\n')
1915

16+
if len(splitted) > 1:
17+
return splitted[0].rstrip().rstrip('.…') + '…'
2018

19+
return text

tasks/apps/tree/urls.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@
3232
path('observations/closed/', views.ObservationClosedListView.as_view(), name='public-observation-list-closed'),
3333
path('diary/<int:year>/<int:month>/', views.JournalArchiveMonthView.as_view(month_format="%m"), name='public-diary-archive-month'),
3434
path('diary/', views.JournalCurrentMonthArchiveView.as_view(month_format="%m"), name='public-diary-archive-current-month'),
35+
path('events/', views.EventCurrentMonthArchiveView.as_view(month_format="%m"), name='public-event-archive-current-month'),
36+
path('events/<int:year>/<int:month>/', views.EventArchiveMonthView.as_view(month_format="%m"), name='public-event-archive-month'),
3537
re_path(r'^observations/closed/(?P<event_stream_id>[a-f0-9\-]+)/$', views.observation_closed_detail, name='public-observation-closed-detail'),
3638

3739
re_path(r'^observations/(?P<observation_id>[a-f0-9\-]+)/close/$', views.observation_close, name='public-observation-close'),

tasks/apps/tree/views.py

Lines changed: 29 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -614,23 +614,45 @@ def get_context_data(self, **kwargs):
614614
)
615615
return context
616616

617+
class EventArchiveContextMixin:
618+
def get_context_data(self, **kwargs):
619+
context = super().get_context_data(**kwargs)
620+
context['dates'] = Event.objects.dates(
621+
'published',
622+
'month',
623+
order='DESC'
624+
)
625+
return context
626+
627+
class CurrentMonthArchiveView(MonthArchiveView):
628+
def get_month(self):
629+
return timezone.now().month
630+
631+
def get_year(self):
632+
return timezone.now().year
617633

618-
class JournalCurrentMonthArchiveView(JournalArchiveContextMixin, MonthArchiveView):
634+
635+
class JournalCurrentMonthArchiveView(JournalArchiveContextMixin, CurrentMonthArchiveView):
619636
model = JournalAdded
620637
date_field = 'published'
621638
allow_future = True
622639

623640

624641
template_name = 'tree/journaladded_archive_month.html'
625642

626-
def get_month(self):
627-
return timezone.now().month
628-
629-
def get_year(self):
630-
return timezone.now().year
631-
632643

633644
class JournalArchiveMonthView(JournalArchiveContextMixin, MonthArchiveView):
634645
model = JournalAdded
635646
date_field = 'published'
636647
allow_future = True
648+
649+
650+
class EventCurrentMonthArchiveView(EventArchiveContextMixin, CurrentMonthArchiveView):
651+
model = Event
652+
date_field = 'published'
653+
allow_future = True
654+
655+
class EventArchiveMonthView(EventArchiveContextMixin, MonthArchiveView):
656+
model = Event
657+
date_field = 'published'
658+
allow_future = True

tasks/assets/styles/example.scss

Lines changed: 37 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -942,32 +942,48 @@ article.quest {
942942

943943
.event {
944944
margin: 0.4em 0;
945+
946+
.event-meta {
947+
margin: 1em 0;
948+
}
945949

946950
.minus {
947-
border-left: 8px solid salmon;
951+
border-left: 4px solid salmon;
948952
color: salmon;
949-
padding-left: 0.2em;
953+
padding-left: 1rem;
954+
display: block;
950955
}
951956

952957
.plus {
953-
border-left: 8px solid lightseagreen;
958+
border-left: 4px solid lightseagreen;
954959
color: lightseagreen;
955-
padding-left: 0.2em;
960+
padding-left: 1rem;
961+
display: block;
956962
}
957963

958964
.minus p, .plus p {
959-
margin: 0;
960965
}
961966

962967
ins.empty, del.empty {
963968
opacity: 0.5;
969+
margin: 1em 0;
964970
text-decoration: none;
965971
font-style:italic;
966972
}
967973

968974
ins, del {
969975
display: block;
970-
padding: 0.2em 0;
976+
}
977+
978+
.observation-ref, .observation-ref a {
979+
font-size: 0.875em;
980+
color: #999;
981+
}
982+
983+
blockquote.situation {
984+
border-left: 4px solid #eee;
985+
padding-left: 1rem;
986+
margin-left: 0;
971987
}
972988
}
973989

@@ -1008,17 +1024,22 @@ section.journal {
10081024
margin-top: 0;
10091025
list-style: none;
10101026
}
1011-
1012-
}
1027+
}
10131028

1014-
p[data-time]::before {
1015-
content: attr(data-time);
1016-
font-size: 0.875em;
1017-
font-weight: bold;
1018-
color: #999;
1019-
margin-right: 0.25em;
1020-
position: absolute;
1021-
left: -3.24rem;
1029+
[data-time] {
1030+
&::before {
1031+
content: attr(data-time);
1032+
font-size: 0.875em;
1033+
font-weight: bold;
1034+
color: #999;
1035+
margin-right: 0.25em;
1036+
position: absolute;
1037+
left: -3.24rem;
1038+
}
1039+
1040+
time {
1041+
display: none;
1042+
}
10221043
}
10231044
}
10241045
}

0 commit comments

Comments
 (0)