Skip to content

Commit

Permalink
Implement board member details as snippet
Browse files Browse the repository at this point in the history
  • Loading branch information
hancush committed Dec 20, 2024
1 parent 431a943 commit fb66d1e
Show file tree
Hide file tree
Showing 16 changed files with 500 additions and 200 deletions.
31 changes: 0 additions & 31 deletions lametro/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
from haystack.query import EmptySearchQuerySet

from councilmatic_core.views import CouncilmaticSearchForm
from lametro.models import LAMetroPerson


class LAMetroCouncilmaticSearchForm(CouncilmaticSearchForm):
Expand Down Expand Up @@ -151,33 +150,3 @@ def clean_agenda(self):
return agenda_pdf
else:
raise forms.ValidationError("File type not supported. Please submit a PDF.")


class PersonHeadshotForm(forms.ModelForm):
headshot_form = forms.BooleanField(widget=forms.HiddenInput, initial=True)

def __init__(self, *args, **kwargs):
super(PersonHeadshotForm, self).__init__(*args, **kwargs)
self.fields["headshot"].widget.attrs.update(
{
"required": "True",
}
)

class Meta:
model = LAMetroPerson
fields = ["headshot"]


class PersonBioForm(forms.ModelForm):
bio_form = forms.BooleanField(widget=forms.HiddenInput, initial=True)

def __init__(self, *args, **kwargs):
super(PersonBioForm, self).__init__(*args, **kwargs)
self.fields["councilmatic_biography"].widget.attrs.update(
{"rows": "5", "required": "True"}
)

class Meta:
model = LAMetroPerson
fields = ["councilmatic_biography"]
132 changes: 132 additions & 0 deletions lametro/migrations/0018_boardmemberdetails.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
# Generated by Django 3.2.25 on 2024-12-20 15:25

from django.db import migrations, models
import django.db.models.deletion
import wagtail.fields
import wagtail.models


class Migration(migrations.Migration):

dependencies = [
("wagtailimages", "0025_alter_image_file_alter_rendition_file"),
("wagtailcore", "0089_log_entry_data_json_null_to_object"),
("lametro", "0017_alter_alert_description"),
]

operations = [
migrations.CreateModel(
name="BoardMemberDetails",
fields=[
(
"id",
models.AutoField(
auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
(
"live",
models.BooleanField(
default=True, editable=False, verbose_name="live"
),
),
(
"has_unpublished_changes",
models.BooleanField(
default=False,
editable=False,
verbose_name="has unpublished changes",
),
),
(
"first_published_at",
models.DateTimeField(
blank=True,
db_index=True,
null=True,
verbose_name="first published at",
),
),
(
"last_published_at",
models.DateTimeField(
editable=False, null=True, verbose_name="last published at"
),
),
(
"go_live_at",
models.DateTimeField(
blank=True, null=True, verbose_name="go live date/time"
),
),
(
"expire_at",
models.DateTimeField(
blank=True, null=True, verbose_name="expiry date/time"
),
),
(
"expired",
models.BooleanField(
default=False, editable=False, verbose_name="expired"
),
),
(
"headshot_source",
models.CharField(
blank=True, default="Metro", max_length=256, null=True
),
),
("bio", wagtail.fields.RichTextField(blank=True, null=True)),
(
"headshot",
models.ForeignKey(
blank=True,
null=True,
on_delete=django.db.models.deletion.SET_NULL,
related_name="+",
to="wagtailimages.image",
),
),
(
"latest_revision",
models.ForeignKey(
blank=True,
editable=False,
null=True,
on_delete=django.db.models.deletion.SET_NULL,
related_name="+",
to="wagtailcore.revision",
verbose_name="latest revision",
),
),
(
"live_revision",
models.ForeignKey(
blank=True,
editable=False,
null=True,
on_delete=django.db.models.deletion.SET_NULL,
related_name="+",
to="wagtailcore.revision",
verbose_name="live revision",
),
),
(
"person",
models.OneToOneField(
on_delete=django.db.models.deletion.CASCADE,
related_name="details",
to="lametro.lametroperson",
),
),
],
options={
"verbose_name_plural": "Board Member Details",
},
bases=(wagtail.models.PreviewableMixin, models.Model),
),
]
62 changes: 61 additions & 1 deletion lametro/models/cms.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
from django.contrib.contenttypes.fields import GenericRelation
from django.db import models
from django.urls import reverse
from django.utils.html import format_html, strip_tags

from wagtail.models import Page
from wagtail.models import Page, PreviewableMixin, DraftStateMixin, RevisionMixin
from wagtail.fields import StreamField, RichTextField
from wagtail.admin.panels import FieldPanel
from wagtail.rich_text import expand_db_html
Expand All @@ -24,6 +26,64 @@ class AboutPage(Page):
]


class BoardMemberDetails(
DraftStateMixin, RevisionMixin, PreviewableMixin, models.Model
):
include_in_dump = True

class Meta:
verbose_name_plural = "Board Member Details"

person = models.OneToOneField(
"lametro.LAMetroPerson", on_delete=models.CASCADE, related_name="details"
)
headshot = models.ForeignKey(
"wagtailimages.Image",
null=True,
blank=True,
on_delete=models.SET_NULL,
related_name="+",
)
headshot_source = models.CharField(
max_length=256, blank=True, null=True, default="Metro"
)
bio = RichTextField(blank=True, null=True)
_revisions = GenericRelation(
"wagtailcore.Revision", related_query_name="member_details"
)

@property
def revisions(self):
return self._revisions

def get_url(self):
return reverse("lametro:person", kwargs={"slug": self.person.slug})

def __str__(self):
loaded_obj = (
type(self)
.objects.select_related("person")
.prefetch_related("person__memberships")
.get(id=self.id)
)
return f"{loaded_obj.person.name}{' (current)' if loaded_obj.person.current_memberships.exists() else ''}"

def get_preview_context(self, request, mode_name):
context = super().get_preview_context(request, mode_name)
context["person"] = self.person
context["person_details"] = self

council_post = self.person.latest_council_membership.post
context["qualifying_post"] = council_post.acting_label

context["preview"] = True

return context

def get_preview_template(self, request, mode_name):
return "person/person.html"


class Alert(models.Model):
include_in_dump = True

Expand Down
5 changes: 3 additions & 2 deletions lametro/models/legislative.py
Original file line number Diff line number Diff line change
Expand Up @@ -469,8 +469,9 @@ def ceo(cls):

@property
def headshot_url(self):
if self.headshot:
return self.headshot.url
print(self.details.headshot)
if self.details.headshot:
return self.details.headshot

file_directory = os.path.dirname(__file__)
absolute_file_directory = os.path.abspath(file_directory)
Expand Down
12 changes: 12 additions & 0 deletions lametro/signals/handlers.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
from django.db.models.signals import post_save
from django.dispatch import receiver

from lametro.models import LAMetroPerson, BoardMemberDetails


@receiver(post_save, sender=LAMetroPerson)
def create_member_details(sender, instance, created, **kwargs):
details_exist = BoardMemberDetails.objects.filter(person=instance).exists()

if not details_exist:
BoardMemberDetails.objects.create(person=instance)
9 changes: 5 additions & 4 deletions lametro/static/css/city_custom.css
Original file line number Diff line number Diff line change
Expand Up @@ -367,10 +367,6 @@ hr .events-line {
.current-meeting-img {
max-width: 75%;
}

#person-detail-headshot {
max-height: none;
}
}

@media only screen and (max-width : 415px) {
Expand Down Expand Up @@ -818,3 +814,8 @@ caption {
.alert p:last-of-type {
margin: unset;
}

.thumbnail-square {
width: 75px;
height: 75px;
}
4 changes: 3 additions & 1 deletion lametro/templates/board_members/_council_member_table.html
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@
<tr id="polygon-{{ membership.post.label | slugify }}-{{ membership.person.name | slugify}}" data-name="{{ membership.person.name | slugify}}" data-polygon="polygon-{{ membership.post.label | slugify }}">
<td>
<div class="thumbnail-square">
<img src='{{ membership.person.headshot_url }}' alt='{{ membership.person.name }}' title='{{ membership.person.name }}' class='img-thumbnail' />
{% with person=membership.person aspect_ratio="fill-100x100" %}
{% include 'common/headshot.html' %}
{% endwith %}
</div>
</td>

Expand Down
8 changes: 6 additions & 2 deletions lametro/templates/committee.html
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,9 @@ <h2 class="d-inline h4">
<tr>
<td data-order="{{ membership.index }}">
<div class="thumbnail-square">
<img src="{{ membership.person.headshot_url }}" alt="{{membership.person.name}}" title="{{membership.person.name}}" class="img-responsive img-thumbnail">
{% with person=membership.person %}
{% include "common/headshot.html" %}
{% endwith %}
</div>
</td>
<td>
Expand Down Expand Up @@ -107,7 +109,9 @@ <h2 class="d-inline h4">
<tr>
<td class="w-12pcnt">
<div class="thumbnail-square">
<img src="{{ ceo.headshot_url }}" alt="{{ceo.name}}" title="{{ceo.name}}" class="img-responsive img-thumbnail">
{% with person=ceo %}
{% include "common/headshot.html" %}
{% endwith %}
</div>
</td>
<td class="w-22pcnt"><a href="{% url 'lametro:person' ceo.slug %}">{{ ceo.name }}</a></td>
Expand Down
11 changes: 11 additions & 0 deletions lametro/templates/common/headshot.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{% load static wagtailimages_tags %}

{% if person.details.headshot %}
{% if original %}
{% image person.details.headshot width-640 class="img-fluid rounded-3 p-1" alt=person.name %}
{% else %}
{% image person.details.headshot fill-100x100 class="img-fluid rounded-3 p-1" alt=person.name %}
{% endif %}
{% else %}
<img src='{% static "images/headshot_placeholder.png" %}' alt="{{person.name}}" title="{{person.name}}" class="img-fluid rounded-3 p-1" id="person-detail-headshot" />
{% endif %}
39 changes: 25 additions & 14 deletions lametro/templates/person/_person_ceo.html
Original file line number Diff line number Diff line change
@@ -1,27 +1,38 @@
{% load extras %}
{% load lametro_extras %}
{% load lametro_extras wagtailcore_tags %}


<div class="row">
<div class="col-md-4">
<img src='{{person.headshot_url}}' alt='{{person.name}}' title='{{person.name}}' class='img-responsive img-thumbnail img-padded' id="person-detail-headshot" />
<div class="col-sm-4 col-md-12">
{% include "common/headshot.html" %}
{% if person_details.headshot %}
<p class="small">
<i class="fa fa-fw fa-camera" aria-hidden="true"></i>
Credit: {{person_details.headshot_source}}
</p>
{% endif %}
</div>

<div class="col-sm-6 col-md-12 mt-3 mt-md-0">
{% if qualifying_post %}
<p class="small mb-1">
<i class='fa fa-fw fa-briefcase' aria-hidden="true"></i>
{{ qualifying_post | appointment_label }}
</p>
{% endif %}

{% if person.headshot_source %}
<p class='small mb-1'>
<i class='fa fa-fw fa-camera' aria-hidden="true"></i>
Credit: {{person.headshot_source}}
</p>
{% endif %}
</div>
<p class="small">
<a href="/about/#about-la-metro">
<i class="fa fa-info-circle" aria-hidden="true"></i>
More about Metro appointments
</a>
</p>
</div>

<div class="col-md-8 mt-3">
<h3>About {{ ceo.name }}</h3>
<p>{{ member_bio | safe }}</p>
</div>
{% if person_details.bio %}
<div class="col-md-8 mt-3">
<h3>About {{ person.name }}</h3>
<p>{{ person_details.bio | richtext }}</p>
</div>
{% endif %}
</div>
Loading

0 comments on commit fb66d1e

Please sign in to comment.