diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index d734e89f..7a813336 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -15,5 +15,5 @@ repos: rev: '9f60881' hooks: - id: flake8 - files: lametro councilmatic tests + files: ^(lametro|councilmatic|tests) exclude: lametro/migrations councilmatic/settings.py diff --git a/councilmatic/settings.py b/councilmatic/settings.py index ca89a51f..67bf0bb7 100644 --- a/councilmatic/settings.py +++ b/councilmatic/settings.py @@ -125,7 +125,6 @@ "debug_toolbar", "template_profiler_panel", "captcha", - "markdownify.apps.MarkdownifyConfig", "wagtail.contrib.forms", "wagtail.contrib.redirects", "wagtail.contrib.typed_table_block", @@ -137,6 +136,7 @@ "wagtail.images", "wagtail.search", "wagtail.admin", + "wagtail.contrib.modeladmin", "wagtail", "modelcluster", "taggit", @@ -329,19 +329,6 @@ def custom_sampler(ctx): }, } - -# Allow some html tags to render in markdown. Mainly for alerts -MARKDOWNIFY = { - "default": { - "WHITELIST_TAGS": [ - "br", - "strong", - "em", - "a", - ] - } -} - # Hard time limit on HTTP requests REQUEST_TIMEOUT = 5 diff --git a/councilmatic/urls.py b/councilmatic/urls.py index 4e2aa204..e02a6f10 100644 --- a/councilmatic/urls.py +++ b/councilmatic/urls.py @@ -44,9 +44,6 @@ MinutesView, pong, test_logging, - AlertCreateView, - AlertDeleteView, - AlertUpdateView, ) from lametro.feeds import LAMetroPersonDetailFeed @@ -119,9 +116,6 @@ manual_event_live_link, name="manual_event_live_link", ), - path("alerts/", AlertCreateView.as_view(), name="alerts"), - path("alerts//delete/", AlertDeleteView.as_view(), name="delete_alert"), - path("alerts//update/", AlertUpdateView.as_view(), name="update_alert"), url( r"^pong/$", pong, diff --git a/lametro/forms.py b/lametro/forms.py index 7fdc7f6e..f42b7b12 100644 --- a/lametro/forms.py +++ b/lametro/forms.py @@ -2,7 +2,6 @@ from django import forms from django.core.files.uploadedfile import InMemoryUploadedFile -from django.core.exceptions import ValidationError from captcha.fields import ReCaptchaField from captcha.fields import ReCaptchaV3 @@ -11,8 +10,7 @@ from haystack.query import EmptySearchQuerySet from councilmatic_core.views import CouncilmaticSearchForm - -from lametro.models import LAMetroPerson, Alert +from lametro.models import LAMetroPerson class LAMetroCouncilmaticSearchForm(CouncilmaticSearchForm): @@ -183,23 +181,3 @@ def __init__(self, *args, **kwargs): class Meta: model = LAMetroPerson fields = ["councilmatic_biography"] - - -class AlertForm(forms.ModelForm): - def clean_description(self): - data = self.cleaned_data.get("description", None) - if not data: - raise ValidationError("Please provide an alert description") - return data - - class Meta: - model = Alert - fields = "__all__" - widgets = { - "description": forms.Textarea( - attrs={ - "rows": 4, - "placeholder": "Enter alert text", - } - ), - } diff --git a/lametro/migrations/0017_alter_alert_description.py b/lametro/migrations/0017_alter_alert_description.py new file mode 100644 index 00000000..4f553ea6 --- /dev/null +++ b/lametro/migrations/0017_alter_alert_description.py @@ -0,0 +1,19 @@ +# Generated by Django 3.2.25 on 2024-12-04 19:18 + +from django.db import migrations +import wagtail.fields + + +class Migration(migrations.Migration): + dependencies = [ + ("lametro", "0016_alter_aboutpage_body"), + ] + + operations = [ + migrations.AlterField( + model_name="alert", + name="description", + field=wagtail.fields.RichTextField(default="No content"), + preserve_default=False, + ), + ] diff --git a/lametro/models/cms.py b/lametro/models/cms.py index dc2baab7..13aa6306 100644 --- a/lametro/models/cms.py +++ b/lametro/models/cms.py @@ -1,6 +1,10 @@ +from django.db import models +from django.utils.html import format_html, strip_tags + from wagtail.models import Page -from wagtail.fields import StreamField +from wagtail.fields import StreamField, RichTextField from wagtail.admin.panels import FieldPanel +from wagtail.rich_text import expand_db_html from lametro.blocks import ArticleBlock @@ -18,3 +22,38 @@ class AboutPage(Page): content_panels = Page.content_panels + [ FieldPanel("body"), ] + + +class Alert(models.Model): + include_in_dump = True + + def __str__(self): + return f"{self.get_type_display()} Alert - {strip_tags(self.description)[:50]}" + + TYPE_CHOICES = [ + ("primary", "Primary"), + ("secondary", "Secondary"), + ("success", "Success"), + ("danger", "Danger"), + ("warning", "Warning"), + ("info", "Info"), + ] + + description = RichTextField() + type = models.CharField(max_length=255, choices=TYPE_CHOICES) + + panels = [ + FieldPanel( + "type", + help_text="Select a style for your alert.", + ), + FieldPanel("description"), + ] + + def content(self): + return format_html( + "
" + + expand_db_html(self.description) + + f"{self.get_type_display()}" + + "
" + ) diff --git a/lametro/models/legislative.py b/lametro/models/legislative.py index 7533db2b..6fb8d38c 100644 --- a/lametro/models/legislative.py +++ b/lametro/models/legislative.py @@ -1237,17 +1237,3 @@ def __str__(self): else: return self.name - - -class Alert(models.Model): - TYPE_CHOICES = [ - ("primary", "Primary"), - ("secondary", "Secondary"), - ("success", "Success"), - ("danger", "Danger"), - ("warning", "Warning"), - ("info", "Info"), - ] - - description = models.TextField(null=True, blank=True) - type = models.CharField(max_length=255, choices=TYPE_CHOICES) diff --git a/lametro/static/css/city_custom.css b/lametro/static/css/city_custom.css index 6acb76dd..9808f930 100644 --- a/lametro/static/css/city_custom.css +++ b/lametro/static/css/city_custom.css @@ -814,3 +814,7 @@ caption { .scroll-anchor { scroll-margin-top: 80px; } + +.alert p:last-of-type { + margin: unset; +} diff --git a/lametro/static/css/wagtail_custom.css b/lametro/static/css/wagtail_custom.css new file mode 100644 index 00000000..b7cb7e85 --- /dev/null +++ b/lametro/static/css/wagtail_custom.css @@ -0,0 +1,58 @@ +[class*="alert"] { + --font-color: #fff; + --a: 0.6; + background-color: rgba(var(--r), var(--g), var(--b), var(--a)); + color: var(--font-color); + border: 1px solid rgba(var(--r), var(--g), var(--b), 1)!important; +} + +.button[class*="alert"]:hover { + background-color: rgba(var(--r), var(--g), var(--b), var(--a)); + color: var(--font-color); +} + +/* Add default border to empty alert select */ +.alert- { + border: 1px solid var(--w-color-border-field-default)!important; +} + +.alert-primary { + --r: 235; + --g: 104; + --b: 100; +} + +.alert-secondary { + --r: 170; + --g: 170; + --b: 170; +} + +.alert-success { + --r: 34; + --g: 178; + --b: 76; +} + +.alert-danger { + --r: 51; + --g: 153; + --b: 153; +} + +.alert-warning { + --font-color: #000; + --r: 245; + --g: 230; + --b: 37; +} + +.alert-info { + --r: 245; + --g: 122; + --b: 0; +} + +.list-display-wrapper { + font-weight: normal!important; +} diff --git a/lametro/static/js/alert-editor.js b/lametro/static/js/alert-editor.js deleted file mode 100644 index 26089169..00000000 --- a/lametro/static/js/alert-editor.js +++ /dev/null @@ -1,35 +0,0 @@ -function styleInputs(element) { - $(element).removeClass() - let description_input = $("#id_description") - - description_input.removeClass() - if (element.value != "") { - $(element).addClass("alert alert-" + element.value) - description_input.addClass("alert alert-" + element.value) - } -} - -$(document).ready(styleInputs($("#id_type")[0])); - -$("#id_type").on('change', function() { - styleInputs(this) -}); - -$(".rich-text-btn").on('click', function() { - let input = document.getElementById("id_description") - - switch(this.id.split('-')[1]) { - case "link": - input.value += ("[this is a link!](https://url.com) ") - break; - case "bold": - input.value += ("**this is bolded text!** ") - break; - case "italic": - input.value += ("*this is italicized text!* ") - break; - case "break": - input.value += ("\n
\n") - break; - } -}); diff --git a/lametro/static/js/wagtail_custom.js b/lametro/static/js/wagtail_custom.js new file mode 100644 index 00000000..d7548a89 --- /dev/null +++ b/lametro/static/js/wagtail_custom.js @@ -0,0 +1,37 @@ +ALERT_COLORS = { + "primary": "#eb6864", + "secondary": "#aaa", + "success": "#22b24c", + "danger": "#369", + "warning": "#f5e625", + "info": "#f57a00", +} + +function styleParent(e) { + if (e.target.classList.length > 0) { + e.target.classList = "" + } + e.target.classList.add(`alert-${e.target.value}`); +} + +// Callback function to execute when mutations are observed +const styleAlertTypeSelect = (mutationList, observer) => { + mutationList.map(mu => { + mu.addedNodes && mu.addedNodes.forEach(node => { + if (node.id === "id_type") { + styleParent({target: node}) + node.addEventListener("change", styleParent) + observer.disconnect() + return + } + }) + }) +}; + +// Create an observer instance linked to the callback function +const observer = new MutationObserver(styleAlertTypeSelect); + +const config = {childList: true, subtree: true}; + +// Start observing the target node for configured mutations +observer.observe(document.body, config); diff --git a/lametro/templates/alerts/_alert_form_inputs.html b/lametro/templates/alerts/_alert_form_inputs.html deleted file mode 100644 index da2009c3..00000000 --- a/lametro/templates/alerts/_alert_form_inputs.html +++ /dev/null @@ -1,31 +0,0 @@ -{% csrf_token %} -

- {{form.type.label_tag}} {{form.type}} -

- -

- {{form.description.label_tag}} -

- -
-
- - - - -
- - {{form.description}} -
- -{% for error in form.description.errors %} - *{{error|striptags}} -{% endfor %} diff --git a/lametro/templates/alerts/alert_edit.html b/lametro/templates/alerts/alert_edit.html deleted file mode 100644 index 25559d45..00000000 --- a/lametro/templates/alerts/alert_edit.html +++ /dev/null @@ -1,20 +0,0 @@ -{% extends "base_with_margins.html" %} -{% load static %} -{% block title %}Edit Alert{% endblock %} - -{% block content %} -

Edit Alert

-
-
- {% include "alerts/_alert_form_inputs.html" %} -
- Cancel - -
-
-
-{% endblock %} - -{% block extra_js %} - -{% endblock %} diff --git a/lametro/templates/alerts/alerts.html b/lametro/templates/alerts/alerts.html deleted file mode 100644 index f9f3d3e3..00000000 --- a/lametro/templates/alerts/alerts.html +++ /dev/null @@ -1,62 +0,0 @@ -{% extends "base_with_margins.html" %} -{% load static %} -{% block title %}Alert Manager{% endblock %} - -{% block content %} -

Alert Manager

- -
-
-
-

Existing Alerts

- {% if alerts %} - - - - - - - - {% for alert in alerts|dictsort:"pk" %} - - - - - - {% endfor %} - -
TypeDescription
{{alert.type|title}}{{alert.description}} - - Edit - -
- {% csrf_token %} - -
-
- {% else %} -

No Alerts Added

- {% endif %} -
- -
-

Add New

-
- {% include "alerts/_alert_form_inputs.html" %} -
- -
- -
-
-
- -
- -
-
-{% endblock %} - -{% block extra_js %} - -{% endblock %} diff --git a/lametro/templates/base.html b/lametro/templates/base.html index 682765d2..4a649b9d 100644 --- a/lametro/templates/base.html +++ b/lametro/templates/base.html @@ -1,4 +1,4 @@ -{% load adv_cache extras lametro_extras markdownify static wagtailcore_tags %} +{% load adv_cache extras lametro_extras static wagtailcore_tags wagtailuserbar %} @@ -73,25 +73,7 @@ {% nocache %} - {% if user.is_authenticated %} - - - {% else %} -
  • - {% endif %} +
  • {% endnocache %} @@ -103,7 +85,7 @@ {% if alerts %} {% for alert in alerts|dictsort:"pk" %}
    - {{alert.description|markdownify}} + {{alert.description|richtext}}
    {% endfor %} {% endif %} @@ -115,6 +97,8 @@ {% endblock %} + {% wagtailuserbar 'bottom-left' %} +