-
Notifications
You must be signed in to change notification settings - Fork 24
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(communications): render news modal on first device visit
feat(communications/admin): AnnouncementCampaign admin and validation fix(AnnouncementCampaignAdminForm): modifying date range feat(communications): render news modal on first device visit feat(communications): implemented a cache for AnnouncementCampaign greatly restricts database usage AnnouncementItemFactory: French locale and better string content refactor(CommunicationsConfig): django signals safe to import at module level refactor(communications): model changes requested in feedback refactor(communications): implemented requested cache changes fix: make quality fix(communications): AnnouncementCampaign ordering fix(static): delete unused image file feat(communications): AnnouncementItem.unique_together on campaign and priority refactor(communications): cache changes, added live field refactor(communications): UniqueConstraint on start_date refactor(communications/cache): rename variable make quality requested changes fix: tests for new constraint suggested changes
- Loading branch information
1 parent
189e0a0
commit 2caf816
Showing
15 changed files
with
607 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
from django.contrib import admin | ||
|
||
from itou.communications import models | ||
from itou.utils.admin import ItouModelAdmin, ItouTabularInline | ||
|
||
|
||
class AnnouncementItemInline(ItouTabularInline): | ||
model = models.AnnouncementItem | ||
fields = ("priority", "title", "description") | ||
extra = 0 | ||
|
||
|
||
@admin.register(models.AnnouncementCampaign) | ||
class AnnouncementCampaignAdmin(ItouModelAdmin): | ||
list_display = ("start_date", "end_date", "live") | ||
fields = ("max_items", "start_date", "live") | ||
inlines = (AnnouncementItemInline,) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
from datetime import date, datetime | ||
|
||
from django.core.cache import cache | ||
|
||
from itou.communications.models import AnnouncementCampaign | ||
|
||
|
||
CACHE_ACTIVE_ANNOUNCEMENTS_KEY = "active-announcement-campaign" | ||
SENTINEL_ACTIVE_ANNOUNCEMENT = object() | ||
|
||
|
||
def update_active_announcement_cache(): | ||
campaign = ( | ||
AnnouncementCampaign.objects.filter(start_date=date.today().replace(day=1), live=True) | ||
.prefetch_related("items") | ||
.first() | ||
) | ||
|
||
if campaign is None: | ||
cache.set(CACHE_ACTIVE_ANNOUNCEMENTS_KEY, None, None) | ||
else: | ||
cache_exp = ( | ||
datetime.combine(campaign.end_date, datetime.min.time()) - datetime.now() | ||
).total_seconds() # seconds until the end_date, 00:00 | ||
|
||
cache.set(CACHE_ACTIVE_ANNOUNCEMENTS_KEY, campaign, cache_exp) | ||
|
||
return campaign | ||
|
||
|
||
def get_cached_active_announcement(): | ||
campaign = cache.get(CACHE_ACTIVE_ANNOUNCEMENTS_KEY, SENTINEL_ACTIVE_ANNOUNCEMENT) | ||
if campaign == SENTINEL_ACTIVE_ANNOUNCEMENT: | ||
return update_active_announcement_cache() | ||
return campaign |
97 changes: 97 additions & 0 deletions
97
itou/communications/migrations/0002_announcementcampaign_announcementitem_and_more.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
# Generated by Django 5.0.7 on 2024-07-23 17:27 | ||
|
||
import django.core.validators | ||
import django.db.models.deletion | ||
import django.db.models.functions.datetime | ||
from django.db import migrations, models | ||
|
||
|
||
class Migration(migrations.Migration): | ||
dependencies = [ | ||
("communications", "0001_initial"), | ||
] | ||
|
||
operations = [ | ||
migrations.CreateModel( | ||
name="AnnouncementCampaign", | ||
fields=[ | ||
("id", models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name="ID")), | ||
( | ||
"max_items", | ||
models.PositiveIntegerField( | ||
default=3, | ||
validators=[ | ||
django.core.validators.MinValueValidator(1), | ||
django.core.validators.MaxValueValidator(10), | ||
], | ||
verbose_name="nombre d'articles affiché", | ||
), | ||
), | ||
( | ||
"start_date", | ||
models.DateField( | ||
help_text="le mois des nouveautés. Automatiquement fixé au premier du mois saisi", | ||
verbose_name="mois concerné", | ||
unique=True, | ||
), | ||
), | ||
( | ||
"live", | ||
models.BooleanField( | ||
default=True, help_text="les modifications sont toujours possible", verbose_name="prêt" | ||
), | ||
), | ||
], | ||
options={ | ||
"verbose_name": "campagne d'annonce", | ||
"ordering": ["-start_date"], | ||
}, | ||
), | ||
migrations.CreateModel( | ||
name="AnnouncementItem", | ||
fields=[ | ||
("id", models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name="ID")), | ||
( | ||
"priority", | ||
models.PositiveIntegerField( | ||
default=0, | ||
help_text="le plus bas le valeur, le plus haut dans le fil des articles", | ||
verbose_name="priorité", | ||
), | ||
), | ||
("title", models.TextField(help_text="résumé de nouveauté", verbose_name="titre")), | ||
( | ||
"description", | ||
models.TextField(help_text="détail du nouveauté ; le contenu", verbose_name="description"), | ||
), | ||
], | ||
options={ | ||
"verbose_name": "article d'annonce", | ||
"ordering": ["-campaign__start_date", "priority", "pk"], | ||
}, | ||
), | ||
migrations.AddConstraint( | ||
model_name="announcementcampaign", | ||
constraint=models.CheckConstraint( | ||
check=models.Q(("max_items__gte", 1), ("max_items__lte", 10)), name="max_items_range" | ||
), | ||
), | ||
migrations.AddConstraint( | ||
model_name="announcementcampaign", | ||
constraint=models.CheckConstraint(check=models.Q(("start_date__day", 1)), name="start_on_month"), | ||
), | ||
migrations.AddField( | ||
model_name="announcementitem", | ||
name="campaign", | ||
field=models.ForeignKey( | ||
on_delete=django.db.models.deletion.CASCADE, | ||
related_name="items", | ||
to="communications.announcementcampaign", | ||
verbose_name="campagne", | ||
), | ||
), | ||
migrations.AlterUniqueTogether( | ||
name="announcementitem", | ||
unique_together={("campaign", "priority")}, | ||
), | ||
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
{% load static %} | ||
{% load theme_inclusion %} | ||
{% load django_bootstrap5 %} | ||
|
||
<input id="news-modal-start-date" type="hidden" value="{{ active_campaign_announce.start_date|date:'Y-m-d' }}" /> | ||
|
||
<div class="modal" id="news-modal" tabindex="-1" role="dialog" aria-labelledby="news-modal-label" aria-modal="true"> | ||
<div class="modal-dialog modal-dialog-centered"> | ||
<div class="modal-content"> | ||
<div class="modal-header"> | ||
<h3 class="modal-title" id="news-modal-label">Il y a du nouveau !</h3> | ||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Fermer"></button> | ||
</div> | ||
<div class="modal-body"> | ||
<div class="text-center mb-5" aria-hidden="true"> | ||
<img class="img-fluid color-filter-primary" src="{% static_theme_images 'ico-bicro-important.svg' %}" alt="Dessin d'étoiles" /> | ||
</div> | ||
{% for item in active_campaign_announce.items_for_template %} | ||
<h6>{{ forloop.counter }}. {{ item.title }}</h6> | ||
<p>{{ item.description }}</p> | ||
{% endfor %} | ||
</div> | ||
<div class="modal-footer"> | ||
<a href="https://aide.emplois.inclusion.beta.gouv.fr/hc/fr/categories/25225629682321--Nouveaut%C3%A9s" class="btn btn-sm btn-primary">Voir toutes les nouveautés</a> | ||
</div> | ||
</div> | ||
</div> | ||
</div> | ||
|
||
<script nonce="{{ CSP_NONCE }}"> | ||
$(document).ready(function() { | ||
// news modal is rendered if there are recent updates which haven't been viewed on this device | ||
if (supports_local_storage()) { | ||
let lastNewsModalViewed = localStorage.getItem("lastNewsModalViewed"); | ||
let newsModalUpdated = new Date($("#news-modal-start-date").val()); | ||
|
||
if (!lastNewsModalViewed || new Date(lastNewsModalViewed) < newsModalUpdated) { | ||
localStorage.setItem("lastNewsModalViewed", new Date().toISOString()); | ||
const newsModal = new bootstrap.Modal("#news-modal"); | ||
newsModal.show(); | ||
} | ||
} | ||
}); | ||
</script> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
# serializer version: 1 | ||
# name: TestRenderAnnouncementCampaign.test_campaign_rendered_dashboard | ||
''' | ||
<div aria-labelledby="news-modal-label" aria-modal="true" class="modal" id="news-modal" role="dialog" tabindex="-1"> | ||
<div class="modal-dialog modal-dialog-centered"> | ||
<div class="modal-content"> | ||
<div class="modal-header"> | ||
<h3 class="modal-title" id="news-modal-label">Il y a du nouveau !</h3> | ||
<button aria-label="Fermer" class="btn-close" data-bs-dismiss="modal" type="button"></button> | ||
</div> | ||
<div class="modal-body"> | ||
<div aria-hidden="true" class="text-center mb-5"> | ||
<img alt="Dessin d'étoiles" class="img-fluid color-filter-primary" src="/static/vendor/theme-inclusion/images/ico-bicro-important.svg"/> | ||
</div> | ||
|
||
<h6>1. Item A</h6> | ||
<p>Item A</p> | ||
|
||
<h6>2. Item B</h6> | ||
<p>Item B</p> | ||
|
||
<h6>3. Item C</h6> | ||
<p>Item C</p> | ||
|
||
</div> | ||
<div class="modal-footer"> | ||
<a class="btn btn-sm btn-primary" href="https://aide.emplois.inclusion.beta.gouv.fr/hc/fr/categories/25225629682321--Nouveaut%C3%A9s">Voir toutes les nouveautés</a> | ||
</div> | ||
</div> | ||
</div> | ||
</div> | ||
''' | ||
# --- |
Oops, something went wrong.