Add incoming messages page
This commit is contained in:
parent
1b9fc8652d
commit
e9e263d59d
|
@ -0,0 +1,27 @@
|
||||||
|
{% if page.has_other_pages %}
|
||||||
|
<nav class="pagination is-centered" role="navigation" aria-label="pagination">
|
||||||
|
{% if page.has_previous %}
|
||||||
|
<a class="pagination-previous" href="?page={{ page.previous_page_number }}"><</a>
|
||||||
|
{% else %}
|
||||||
|
<a class="pagination-previous is-disabled"><</a>
|
||||||
|
{% endif %}
|
||||||
|
{% if page.has_next %}
|
||||||
|
<a class="pagination-next" href="?page={{ page.next_page_number }}">></a>
|
||||||
|
{% else %}
|
||||||
|
<a class="pagination-next is-disabled">></a>
|
||||||
|
{% endif %}
|
||||||
|
<ul class="pagination-list">
|
||||||
|
{% for p in page_range %}
|
||||||
|
<li>
|
||||||
|
{% if p == page.paginator.ELLIPSIS %}
|
||||||
|
<span class="pagination-ellipsis">{{ page.paginator.ELLIPSIS }}</span>
|
||||||
|
{% elif p == page.number %}
|
||||||
|
<a class="pagination-link is-current">{{ p }}</a>
|
||||||
|
{% else %}
|
||||||
|
<a class="pagination-link" href="?page={{ p }}">{{ p }}</a>
|
||||||
|
{% endif %}
|
||||||
|
</li>
|
||||||
|
{% endfor %}
|
||||||
|
</ul>
|
||||||
|
</nav>
|
||||||
|
{% endif %}
|
|
@ -50,6 +50,7 @@ INSTALLED_APPS = [
|
||||||
"django.contrib.admin",
|
"django.contrib.admin",
|
||||||
"django.contrib.auth",
|
"django.contrib.auth",
|
||||||
"django.contrib.contenttypes",
|
"django.contrib.contenttypes",
|
||||||
|
"django.contrib.humanize",
|
||||||
"django.contrib.sessions",
|
"django.contrib.sessions",
|
||||||
"django.contrib.messages",
|
"django.contrib.messages",
|
||||||
"django.contrib.staticfiles",
|
"django.contrib.staticfiles",
|
||||||
|
|
|
@ -7,3 +7,4 @@ from .models import IncomingMessage
|
||||||
@admin.register(IncomingMessage)
|
@admin.register(IncomingMessage)
|
||||||
class IncomingMessageAdmin(admin.ModelAdmin):
|
class IncomingMessageAdmin(admin.ModelAdmin):
|
||||||
list_display = ("sender", "created_at")
|
list_display = ("sender", "created_at")
|
||||||
|
readonly_fields = ("id", "sender", "content", "created_at", "read")
|
||||||
|
|
|
@ -0,0 +1,21 @@
|
||||||
|
# Generated by Django 4.0.4 on 2023-05-07 11:52
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
dependencies = [
|
||||||
|
("team", "0002_alter_incomingmessage_id"),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name="incomingmessage",
|
||||||
|
name="read",
|
||||||
|
field=models.BooleanField(default=False),
|
||||||
|
),
|
||||||
|
migrations.AddIndex(
|
||||||
|
model_name="incomingmessage",
|
||||||
|
index=models.Index(fields=["sender"], name="team_incomi_sender_799f7d_idx"),
|
||||||
|
),
|
||||||
|
]
|
|
@ -8,8 +8,20 @@ from shiftregister.app.models import *
|
||||||
class IncomingMessage(models.Model):
|
class IncomingMessage(models.Model):
|
||||||
class Meta:
|
class Meta:
|
||||||
get_latest_by = "created_at"
|
get_latest_by = "created_at"
|
||||||
|
indexes = (models.Index(fields=("sender",)),)
|
||||||
|
|
||||||
id = models.BigIntegerField(primary_key=True)
|
id = models.BigIntegerField(primary_key=True)
|
||||||
sender = PhoneNumberField()
|
sender = PhoneNumberField()
|
||||||
content = models.TextField()
|
content = models.TextField()
|
||||||
created_at = models.DateTimeField()
|
created_at = models.DateTimeField()
|
||||||
|
read = models.BooleanField(default=False)
|
||||||
|
|
||||||
|
def from_helper(self):
|
||||||
|
try:
|
||||||
|
return Helper.objects.get(phone=self.sender)
|
||||||
|
except Helper.DoesNotExist:
|
||||||
|
return None
|
||||||
|
|
||||||
|
def display_sender(self):
|
||||||
|
helper = self.from_helper()
|
||||||
|
return helper.name if helper else self.sender
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
from django.dispatch import receiver
|
from django.dispatch import receiver
|
||||||
from django.shortcuts import reverse
|
from django.shortcuts import reverse
|
||||||
from shiftregister.core.signals import populate_nav
|
from shiftregister.core.signals import populate_nav
|
||||||
|
from .models import IncomingMessage
|
||||||
|
|
||||||
|
|
||||||
@receiver(populate_nav, dispatch_uid="populate_team_nav")
|
@receiver(populate_nav, dispatch_uid="populate_team_nav")
|
||||||
|
@ -20,4 +21,14 @@ def populate_team_nav(sender, **kwargs):
|
||||||
{"link": reverse("team:bulk_message"), "text": "Massen-Nachricht"}
|
{"link": reverse("team:bulk_message"), "text": "Massen-Nachricht"}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
num_unread = IncomingMessage.objects.filter(read=False).count()
|
||||||
|
nav_items.append(
|
||||||
|
{
|
||||||
|
"link": reverse("team:incoming_messages"),
|
||||||
|
"text": "Eingehende Nachrichten" + f" ({num_unread})"
|
||||||
|
if num_unread
|
||||||
|
else "",
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
return nav_items
|
return nav_items
|
||||||
|
|
|
@ -0,0 +1,21 @@
|
||||||
|
{% extends "base.html" %}
|
||||||
|
|
||||||
|
{% load humanize %}
|
||||||
|
|
||||||
|
{% block title %}Sie haben {{ num_unread | apnumber }} neue Nachricht{{ num_unread | pluralize:"en" }}{% endblock %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
{% for message in page %}
|
||||||
|
<a href="{% if message.from_helper %}{% url 'team:helper' message.from_helper.pk %}{% else %}{% url 'team:conversation' message.sender %}{% endif %}">
|
||||||
|
<div class="message{% if not message.read %} is-info{% endif %} mb-5">
|
||||||
|
<div class="message-header">
|
||||||
|
{{ message.display_sender }} <small>{{ message.created_at | naturaltime }}</small>
|
||||||
|
</div>
|
||||||
|
<div class="message-body">
|
||||||
|
{{ message.content }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
{% endfor %}
|
||||||
|
{% include "pagination.html" %}
|
||||||
|
{% endblock %}
|
|
@ -13,4 +13,6 @@ urlpatterns = [
|
||||||
path("message/", views.bulk_message, name="bulk_message"),
|
path("message/", views.bulk_message, name="bulk_message"),
|
||||||
path("checkin/<int:pk>", views.checkin, name="checkin"),
|
path("checkin/<int:pk>", views.checkin, name="checkin"),
|
||||||
path("remove_helper/<int:pk>", views.delete_shiftregistration, name="unregister"),
|
path("remove_helper/<int:pk>", views.delete_shiftregistration, name="unregister"),
|
||||||
|
path("incoming/", views.incoming_messages, name="incoming_messages"),
|
||||||
|
path("incoming/<str:sender>", views.conversation, name="conversation"),
|
||||||
]
|
]
|
||||||
|
|
|
@ -3,11 +3,12 @@ from django.contrib.auth.decorators import login_required
|
||||||
from django.utils import timezone
|
from django.utils import timezone
|
||||||
from django.db.models.fields import DateTimeField
|
from django.db.models.fields import DateTimeField
|
||||||
from django.db.models import F, Count, Q, ExpressionWrapper, Case, When
|
from django.db.models import F, Count, Q, ExpressionWrapper, Case, When
|
||||||
from .models import ShiftRegistration, Room, Shift, Helper, Message
|
from .models import ShiftRegistration, Room, Shift, Helper, Message, IncomingMessage
|
||||||
from django.views.generic import DetailView, ListView
|
from django.views.generic import DetailView, ListView
|
||||||
from django.contrib.auth.mixins import LoginRequiredMixin
|
from django.contrib.auth.mixins import LoginRequiredMixin
|
||||||
from django.contrib import messages
|
from django.contrib import messages
|
||||||
from django.db import models
|
from django.db import models
|
||||||
|
from django.core.paginator import Paginator
|
||||||
from .forms import BulkMessage, HelperShift
|
from .forms import BulkMessage, HelperShift
|
||||||
|
|
||||||
|
|
||||||
|
@ -192,3 +193,24 @@ def delete_shiftregistration(request, pk):
|
||||||
spk = reg.shift.pk
|
spk = reg.shift.pk
|
||||||
reg.delete()
|
reg.delete()
|
||||||
return redirect("team:shift", pk=spk)
|
return redirect("team:shift", pk=spk)
|
||||||
|
|
||||||
|
|
||||||
|
@login_required
|
||||||
|
def incoming_messages(request):
|
||||||
|
p = Paginator(IncomingMessage.objects.order_by("read", "-created_at"), 10)
|
||||||
|
page = p.get_page(request.GET.get("page"))
|
||||||
|
|
||||||
|
return render(
|
||||||
|
request,
|
||||||
|
"incoming_messages.html",
|
||||||
|
{
|
||||||
|
"num_unread": IncomingMessage.objects.filter(read=False).count(),
|
||||||
|
"page": page,
|
||||||
|
"page_range": p.get_elided_page_range(page.number),
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@login_required
|
||||||
|
def conversation(request, sender):
|
||||||
|
pass
|
||||||
|
|
Loading…
Reference in New Issue