Skip to content

Commit

Permalink
Merge pull request #1406 from laws-africa/labels
Browse files Browse the repository at this point in the history
Add labels for documents
  • Loading branch information
nickmwangemi authored Jul 31, 2023
2 parents 0a7b212 + e0adc99 commit 21923ec
Show file tree
Hide file tree
Showing 16 changed files with 222 additions and 14 deletions.
24 changes: 22 additions & 2 deletions peachjam/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@
Journal,
Judge,
Judgment,
Label,
LegalInstrument,
Legislation,
Locality,
Expand Down Expand Up @@ -317,7 +318,12 @@ class DocumentAdmin(admin.ModelAdmin):
exclude = ("doc_type",)
date_hierarchy = "date"
prepopulated_fields = {"frbr_uri_number": ("title",)}
actions = ["extract_citations", "reextract_content", "reindex_for_search"]
actions = [
"extract_citations",
"reextract_content",
"reindex_for_search",
"apply_labels",
]

fieldsets = [
(
Expand Down Expand Up @@ -492,14 +498,22 @@ def reextract_content(self, request, queryset):
reextract_content.short_description = "Re-extract content from DOCX files"

def reindex_for_search(self, request, queryset):
"""Setup a background task to re-index documents for search."""
"""Set up a background task to re-index documents for search."""
count = queryset.count()
for doc in queryset:
search_model_saved(doc._meta.label, doc.pk)
self.message_user(request, f"Queued tasks to re-index for {count} documents.")

reindex_for_search.short_description = "Re-index for search (background)"

def apply_labels(self, request, queryset):
count = queryset.count()
for doc in queryset:
doc.apply_labels()
self.message_user(request, f"Applying labels for {count} documents.")

apply_labels.short_description = "Apply labels"

def has_delete_permission(self, request, obj=None):
if obj:
if (
Expand Down Expand Up @@ -854,6 +868,12 @@ class UserAdminCustom(ImportExportMixin, UserAdmin):
resource_class = UserResource


@admin.register(Label)
class LabelAdmin(admin.ModelAdmin):
list_display = ("name", "code")
prepopulated_fields = {"code": ("name",)}


admin.site.register(
[
Locality,
Expand Down
17 changes: 15 additions & 2 deletions peachjam/js/components/FindDocuments/SearchResult.vue
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,9 @@
<div>
{{ item.matter_type }}
</div>

<div v-if="labels">
<span v-for="label in labels" :key="label.code" :class="[ `badge rounded-pill bg-${label.level}` ]">{{ label.name }}</span>
</div>
<div v-if="item.pages.length" class="ms-3">
<div
v-for="(page, index) in item.pages"
Expand Down Expand Up @@ -71,7 +73,18 @@ export default {
},
showJurisdiction: {
type: Boolean,
default: false,
default: false
},
documentLabels: {
type: Array,
default: () => []
}
},
computed: {
labels () {
// get documentLabels where the code is in item.labels
return this.documentLabels.filter(label => (this.item.labels || []).includes(label.code));
}
},
methods: {
Expand Down
3 changes: 3 additions & 0 deletions peachjam/js/components/FindDocuments/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,7 @@
:item="item"
:query="q"
:showJurisdiction="showJurisdiction"
:documentLabels="documentLabels"
/>
</ul>

Expand Down Expand Up @@ -241,6 +242,7 @@ export default {
data () {
const data = {
searchPlaceholder: JSON.parse(document.querySelector('#data-labels').textContent).searchPlaceholder,
documentLabels: JSON.parse(document.querySelector('#data-labels').textContent).documentLabels,
loadingCount: 0,
error: null,
searchInfo: {},
Expand Down Expand Up @@ -346,6 +348,7 @@ export default {
options: []
});
}
data.facets = facets;
resetAdvancedFields(data.advancedFields);
return data;
Expand Down
80 changes: 80 additions & 0 deletions peachjam/migrations/0093_add_model_labels.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
# Generated by Django 3.2.19 on 2023-07-31 07:47

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
("peachjam", "0092_documentcontent_content_xml"),
]

operations = [
migrations.CreateModel(
name="Label",
fields=[
(
"id",
models.BigAutoField(
auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
(
"name",
models.CharField(max_length=1024, unique=True, verbose_name="name"),
),
(
"name_en",
models.CharField(
max_length=1024, null=True, unique=True, verbose_name="name"
),
),
(
"name_fr",
models.CharField(
max_length=1024, null=True, unique=True, verbose_name="name"
),
),
(
"name_pt",
models.CharField(
max_length=1024, null=True, unique=True, verbose_name="name"
),
),
(
"name_sw",
models.CharField(
max_length=1024, null=True, unique=True, verbose_name="name"
),
),
(
"code",
models.SlugField(max_length=1024, unique=True, verbose_name="code"),
),
(
"level",
models.CharField(
default="info",
help_text="One of: primary, secondary, success, danger, warning or info.",
max_length=1024,
verbose_name="level",
),
),
],
options={
"verbose_name": "label",
"verbose_name_plural": "labels",
"ordering": ["name"],
},
),
migrations.AddField(
model_name="coredocument",
name="labels",
field=models.ManyToManyField(
blank=True, to="peachjam.Label", verbose_name="labels"
),
),
]
41 changes: 38 additions & 3 deletions peachjam/models/core_document_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
from django.core.files import File
from django.db import models
from django.utils.functional import cached_property
from django.utils.text import slugify
from django.utils.translation import gettext_lazy as _
from docpipe.pipeline import PipelineContext
from docpipe.soffice import soffice_convert
Expand All @@ -37,6 +38,34 @@
from peachjam.storage import DynamicStorageFileField


class Label(models.Model):
name = models.CharField(
_("name"), max_length=1024, unique=True, null=False, blank=False
)
code = models.SlugField(_("code"), max_length=1024, unique=True)
level = models.CharField(
_("level"),
max_length=1024,
null=False,
blank=False,
default="info",
help_text="One of: primary, secondary, success, danger, warning or info.",
)

def save(self, *args, **kwargs):
if not self.code:
self.code = slugify(self.name)
return super().save(*args, **kwargs)

class Meta:
verbose_name = _("label")
verbose_name_plural = _("labels")
ordering = ["name"]

def __str__(self):
return f"{self.name}"


class DocumentNature(models.Model):
name = models.CharField(
_("name"), max_length=1024, null=False, blank=False, unique=True
Expand Down Expand Up @@ -396,6 +425,7 @@ class CoreDocument(PolymorphicModel):

# options for the FRBR URI doctypes
frbr_uri_doctypes = FRBR_URI_DOCTYPES
labels = models.ManyToManyField(Label, verbose_name=_("labels"), blank=True)

class Meta:
ordering = ["doc_type", "title"]
Expand All @@ -407,6 +437,9 @@ class Meta:
def __str__(self):
return f"{self.doc_type} - {self.title}"

def apply_labels(self):
pass

def get_all_fields(self):
return self._meta.get_fields()

Expand Down Expand Up @@ -505,10 +538,12 @@ def pre_save(self):
self.work.save()

def save(self, *args, **kwargs):
# give ourselves and subclasses a chance to pre-populate derived fields before saving, in case full_clean() has
# not yet been called
# give ourselves and subclasses a chance to pre-populate derived fields before saving,
# in case full_clean() has not yet been called
self.pre_save()
return super().save(*args, **kwargs)
super().save(*args, **kwargs)
# apply labels
self.apply_labels()

@cached_property
def relationships_as_subject(self):
Expand Down
15 changes: 15 additions & 0 deletions peachjam/models/generic_document.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
CoreDocument,
CoreDocumentManager,
CoreDocumentQuerySet,
Label,
Work,
)
from peachjam.models.author import Author
Expand Down Expand Up @@ -85,6 +86,20 @@ class Meta(CoreDocument.Meta):
def __str__(self):
return self.title

def apply_labels(self):
# label to indicate that this legislation is repealed
label, _ = Label.objects.get_or_create(
code="repealed", defaults={"name": "Repealed", "code": "repealed"}
)
# apply label if repealed
if self.repealed:
self.labels.add(label.pk)
else:
# not repealed, remove label
self.labels.remove(label.pk)

super().apply_labels()

def pre_save(self):
self.doc_type = "legislation"
return super().pre_save()
19 changes: 18 additions & 1 deletion peachjam/models/judgment.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
from django.utils.translation import gettext_lazy as _
from django.utils.translation import override as lang_override

from peachjam.models import CoreDocument
from peachjam.models import CoreDocument, Label


class Attorney(models.Model):
Expand Down Expand Up @@ -284,6 +284,23 @@ def assign_title(self):
self.title = " ".join(parts)
self.citation = self.title

def apply_labels(self):
"""Apply labels to this judgment based on its properties."""
# label showing that a judgment is cited/reported in law reports, hence "more important"
label, _ = Label.objects.get_or_create(
code="reported",
defaults={"name": "Reported", "code": "reported"},
)

# if the judgment has alternative_names, apply the "reported" label
if self.alternative_names.exists():
self.labels.add(label.pk)
# if the judgment no alternative_names, remove the "reported" label
else:
self.labels.remove(label.pk)

super().apply_labels()

def pre_save(self):
# ensure registry aligns to the court
if self.registry:
Expand Down
2 changes: 1 addition & 1 deletion peachjam/static/js/app-prod.js

Large diffs are not rendered by default.

5 changes: 5 additions & 0 deletions peachjam/templates/peachjam/_labels.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{% if labels %}
<div class="d-flex align-items-center">
{% for label in labels %}<span class="badge rounded-pill bg-{{ label.level }}">{{ label.name }}</span>{% endfor %}
</div>
{% endif %}
1 change: 1 addition & 0 deletions peachjam/templates/peachjam/layouts/document_detail.html
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
{% block document-title %}
<div class="d-md-flex justify-content-md-between py-4">
<h1>{{ document.title }}</h1>
{% include 'peachjam/_labels.html' %}
<div class="d-flex align-items-center">
<a href="https://api.whatsapp.com/send?text={{ request.build_absolute_uri }}"
class="btn btn-link"
Expand Down
6 changes: 6 additions & 0 deletions peachjam/translation.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
CourtClass,
CourtRegistry,
DocumentNature,
Label,
OrderOutcome,
Predicate,
Taxonomy,
Expand Down Expand Up @@ -37,6 +38,11 @@ class DocumentNatureTranslationOptions(TranslationOptions):
fields = ("name",)


@register(Label)
class LabelTranslationOptions(TranslationOptions):
fields = ("name",)


@register(OrderOutcome)
class OrderOutcomeTranslationOptions(TranslationOptions):
fields = ("name",)
Expand Down
1 change: 1 addition & 0 deletions peachjam/views/generic_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,7 @@ def get_context_data(self, **kwargs):
context["cited_documents_count"]
+ context["documents_citing_current_doc_count"]
)
context["labels"] = doc.labels.all()

return context

Expand Down
7 changes: 7 additions & 0 deletions peachjam_api/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
from peachjam.models import (
CitationLink,
CoreDocument,
Label,
Legislation,
Predicate,
Relationship,
Expand Down Expand Up @@ -130,3 +131,9 @@ class Meta:
"action",
"data",
)


class LabelSerializer(serializers.ModelSerializer):
class Meta:
model = Label
exclude = []
Loading

0 comments on commit 21923ec

Please sign in to comment.