Skip to content

Commit ea1c64f

Browse files
Implement tabbed navigation for cited cases and legislation within law report volumes and refactor law report detail views.
1 parent d425954 commit ea1c64f

File tree

4 files changed

+151
-87
lines changed

4 files changed

+151
-87
lines changed
Lines changed: 22 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
{% extends 'peachjam/layouts/document_list.html' %}
2-
{% load i18n peachjam %}
3-
{% block title %}{{ page_title }}{% endblock %}
4-
{% block breadcrumbs %}
5-
<div class="container">
1+
{% extends "peachjam/layouts/main.html" %}
2+
{% load i18n %}
3+
{% block title %}{{ law_report.title }}{% endblock %}
4+
{% block page-content %}
5+
<div class="container pb-5">
66
<nav aria-label="breadcrumb">
77
<ol class="breadcrumb">
88
<li class="breadcrumb-item">
@@ -14,35 +14,22 @@
1414
<li class="breadcrumb-item active" aria-current="page">{{ law_report.title }}</li>
1515
</ol>
1616
</nav>
17-
</div>
18-
{% endblock %}
19-
{% block page-header %}
20-
{% block page-title %}
21-
{% if not entity_profile %}
22-
<div class="my-4">
23-
<h1>{{ page_title }}</h1>
24-
{% block follow-button %}{% endblock %}
25-
</div>
17+
{% if entity_profile %}
18+
{% include 'peachjam/_entity_profile.html' with profile=entity_profile %}
19+
{% else %}
20+
<h1 class="my-4">{{ law_report.title }}</h1>
2621
{% endif %}
27-
{% endblock %}
28-
{% if law_report_volumes %}
29-
<div class="flow-columns">
30-
{% for group in law_report_volume_groups %}
31-
<div class="flow-columns-group">
32-
<ul class="list-unstyled">
33-
{% for volume in group %}
34-
{% if law_report_volume and law_report_volume.slug == volume.slug %}
35-
<li>{{ volume.title }}</li>
36-
{% else %}
37-
<li>
38-
<a href="{{ volume.get_absolute_url }}">{{ volume.title }}</a>
39-
</li>
40-
{% endif %}
41-
{% endfor %}
42-
</ul>
43-
</div>
44-
{% endfor %}
45-
</div>
46-
{% endif %}
47-
{% include 'peachjam/_count_and_search.html' %}
22+
<h2>{% trans 'Volumes' %}</h2>
23+
{% if law_report_volumes %}
24+
<ul class="list-unstyled">
25+
{% for volume in law_report_volumes %}
26+
<li class="mb-2">
27+
<a href="{{ volume.get_absolute_url }}">{{ volume.title }}</a>
28+
</li>
29+
{% endfor %}
30+
</ul>
31+
{% else %}
32+
<p>{% trans 'No volumes found.' %}</p>
33+
{% endif %}
34+
</div>
4835
{% endblock %}

peachjam/templates/peachjam/law_report/law_report_list.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ <h1 class="mb-0">{% trans 'Law reports' %}</h1>
2727
<div class="row g-4">
2828
{% for law_report in law_reports %}
2929
<div class="col-12 col-md-6">
30-
{% with profile=journal.entity_profile.first %}
30+
{% with profile=law_report.entity_profile.first %}
3131
<div class="card h-100 border">
3232
<div class="card-body d-flex gap-3 align-items-start">
3333
{% if profile and profile.profile_photo %}

peachjam/templates/peachjam/law_report/law_report_volume_detail.html

Lines changed: 24 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -24,27 +24,31 @@
2424
{% block page-title %}
2525
<div class="my-4">
2626
<h1>{{ page_title }}</h1>
27-
{% block follow-button %}{% endblock %}
2827
</div>
2928
{% endblock %}
30-
{% if law_report_volumes %}
31-
<div class="flow-columns">
32-
{% for group in law_report_volume_groups %}
33-
<div class="flow-columns-group">
34-
<ul class="list-unstyled">
35-
{% for volume in group %}
36-
{% if law_report_volume.slug == volume.slug %}
37-
<li>{{ volume.title }}</li>
38-
{% else %}
39-
<li>
40-
<a href="{{ volume.get_absolute_url }}">{{ volume.title }}</a>
41-
</li>
42-
{% endif %}
43-
{% endfor %}
44-
</ul>
45-
</div>
46-
{% endfor %}
47-
</div>
29+
<a href="{{ law_report.get_absolute_url }}"
30+
class="btn btn-sm btn-outline-secondary mb-3">
31+
<i class="bi bi-arrow-left me-1"></i>{% trans 'Back to law report' %}
32+
</a>
33+
<ul class="nav nav-tabs mb-3">
34+
<li class="nav-item">
35+
<a class="nav-link {% if active_tab == 'judgments' %}active{% endif %}"
36+
href="{{ law_report_volume.get_absolute_url }}">{% trans 'Judgments' %}</a>
37+
</li>
38+
<li class="nav-item">
39+
<a class="nav-link {% if active_tab == 'cases' %}active{% endif %}"
40+
href="{{ law_report_volume.get_absolute_url }}?tab=cases">{% trans 'Cited cases' %}</a>
41+
</li>
42+
<li class="nav-item">
43+
<a class="nav-link {% if active_tab == 'legislation' %}active{% endif %}"
44+
href="{{ law_report_volume.get_absolute_url }}?tab=legislation">{% trans 'Cited legislation' %}</a>
45+
</li>
46+
</ul>
47+
{% include 'peachjam/_document_count.html' %}
48+
{% endblock %}
49+
{% block document-table %}
50+
{% if active_tab != 'judgments' %}
51+
<input type="hidden" name="tab" value="{{ active_tab }}" form="filter-form" />
4852
{% endif %}
49-
{% include 'peachjam/_count_and_search.html' %}
53+
{{ block.super }}
5054
{% endblock %}

peachjam/views/law_reports.py

Lines changed: 104 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,16 @@
1+
from collections import defaultdict
12
from functools import cached_property
23

34
from django.shortcuts import get_object_or_404
4-
from django.views.generic import ListView
5-
6-
from peachjam.helpers import chunks
7-
from peachjam.models import LawReport, LawReportVolume
5+
from django.views.generic import DetailView, ListView
6+
7+
from peachjam.models import (
8+
ExtractedCitation,
9+
Judgment,
10+
LawReport,
11+
LawReportVolume,
12+
Legislation,
13+
)
814
from peachjam.views.courts import FilteredJudgmentView
915

1016

@@ -14,41 +20,33 @@ class LawReportListView(ListView):
1420
context_object_name = "law_reports"
1521

1622

17-
class LawReportDetailView(FilteredJudgmentView):
23+
class LawReportDetailView(DetailView):
1824
template_name = "peachjam/law_report/law_report_detail.html"
25+
model = LawReport
26+
context_object_name = "law_report"
1927
navbar_link = "law_report"
2028

21-
@cached_property
22-
def law_report(self):
23-
return get_object_or_404(
24-
LawReport.objects.prefetch_related("volumes"), slug=self.kwargs.get("slug")
25-
)
26-
27-
def base_view_name(self):
28-
return self.law_report.title
29-
30-
def get_base_queryset(self, exclude=None):
31-
qs = super().get_base_queryset(exclude=exclude)
32-
qs = qs.filter(
33-
law_report_entries__law_report_volume__law_report=self.law_report
34-
)
35-
return qs
36-
3729
def get_context_data(self, **kwargs):
3830
context = super().get_context_data(**kwargs)
39-
context["law_report"] = self.law_report
40-
context["law_report_volumes"] = self.law_report.volumes.exclude(
31+
context["law_report_volumes"] = self.object.volumes.exclude(
4132
law_report_entries__isnull=True
42-
)
43-
context["law_report_volume_groups"] = chunks(context["law_report_volumes"], 3)
44-
context["entity_profile"] = self.law_report.entity_profile.first()
45-
context["entity_profile_title"] = self.law_report.title
46-
context["hide_follow_button"] = True
33+
).order_by("-title")
34+
context["entity_profile"] = self.object.entity_profile.first()
35+
context["entity_profile_title"] = self.object.title
4736
return context
4837

4938

50-
class LawReportVolumeDetailView(LawReportDetailView):
39+
class LawReportVolumeDetailView(FilteredJudgmentView):
5140
template_name = "peachjam/law_report/law_report_volume_detail.html"
41+
navbar_link = "law_report"
42+
43+
CITATION_TABS = {"cases": Judgment, "legislation": Legislation}
44+
45+
@cached_property
46+
def law_report(self):
47+
return get_object_or_404(
48+
LawReport.objects.prefetch_related("volumes"), slug=self.kwargs.get("slug")
49+
)
5250

5351
def base_view_name(self):
5452
return self.law_report_volume.title
@@ -61,12 +59,87 @@ def law_report_volume(self):
6159
slug=self.kwargs.get("volume_slug"),
6260
)
6361

62+
@cached_property
63+
def active_tab(self):
64+
tab = self.request.GET.get("tab")
65+
return tab if tab in self.CITATION_TABS else "judgments"
66+
6467
def get_base_queryset(self, exclude=None):
68+
if self.active_tab in self.CITATION_TABS:
69+
model = self.CITATION_TABS[self.active_tab]
70+
volume_lookup = (
71+
"work__incoming_citations__citing_work__documents"
72+
"__judgment__law_report_entries__law_report_volume"
73+
)
74+
return (
75+
model.objects.filter(
76+
**{volume_lookup: self.law_report_volume},
77+
published=True,
78+
)
79+
.distinct()
80+
.order_by("title")
81+
)
6582
qs = super().get_base_queryset(exclude=exclude)
66-
qs = qs.filter(law_report_entries__law_report_volume=self.law_report_volume)
67-
return qs
83+
return qs.filter(law_report_entries__law_report_volume=self.law_report_volume)
6884

6985
def get_context_data(self, **kwargs):
7086
context = super().get_context_data(**kwargs)
87+
context["law_report"] = self.law_report
7188
context["law_report_volume"] = self.law_report_volume
89+
context["active_tab"] = self.active_tab
90+
91+
if self.active_tab in self.CITATION_TABS:
92+
context["doc_table_toggle"] = True
93+
self._attach_citing_judgments(context.get("documents", []))
94+
7295
return context
96+
97+
def add_facets(self, context):
98+
if self.active_tab in self.CITATION_TABS:
99+
context["facet_data"] = {}
100+
self.add_alphabet_facet(context)
101+
else:
102+
super().add_facets(context)
103+
104+
def _attach_citing_judgments(self, cited_docs):
105+
"""Attach citing judgments from this volume as .children for toggle."""
106+
work_ids = [d.work_id for d in cited_docs if hasattr(d, "work_id")]
107+
if not work_ids:
108+
return
109+
110+
citations = (
111+
ExtractedCitation.objects.filter(
112+
citing_work__documents__judgment__law_report_entries__law_report_volume=self.law_report_volume,
113+
target_work_id__in=work_ids,
114+
)
115+
.values_list("target_work_id", "citing_work_id")
116+
.distinct()
117+
)
118+
119+
citing_map = defaultdict(set)
120+
for target_wid, citing_wid in citations:
121+
citing_map[target_wid].add(citing_wid)
122+
123+
if not citing_map:
124+
return
125+
126+
all_citing_wids = set().union(*citing_map.values())
127+
citing_docs = {
128+
j.work_id: j
129+
for j in Judgment.objects.filter(
130+
work_id__in=all_citing_wids, published=True
131+
)
132+
.distinct("work_frbr_uri")
133+
.order_by("work_frbr_uri", "-date")
134+
}
135+
136+
for doc in cited_docs:
137+
if hasattr(doc, "work_id"):
138+
doc.children = sorted(
139+
[
140+
citing_docs[wid]
141+
for wid in citing_map.get(doc.work_id, [])
142+
if wid in citing_docs
143+
],
144+
key=lambda d: d.title,
145+
)

0 commit comments

Comments
 (0)