2
0
Fork 0

Implement incoming_message view and show message history on helper page

This commit is contained in:
Luca 2023-05-07 17:24:26 +02:00
parent e9e263d59d
commit eb681d31b0
8 changed files with 133 additions and 9 deletions

View File

@ -31,6 +31,14 @@
margin-bottom: 1em;
}
.message-incoming {
margin-right: 20%;
}
.message-outgoing {
margin-left: 20%;
}
.sticky-nav {
background-color: var(--background);
margin: 0 -0.75rem;

View File

@ -23,3 +23,10 @@ class BulkMessage(forms.Form):
checked_in_only = forms.BooleanField(
label="Nur an Helfer*innen mit mindestens einem Check-in senden", required=False
)
class HelperMessage(forms.Form):
message = forms.CharField(
max_length=160,
widget=forms.Textarea(attrs={"class": "textarea", "placeholder": "Nachricht"}),
)

View File

@ -25,9 +25,8 @@ def populate_team_nav(sender, **kwargs):
nav_items.append(
{
"link": reverse("team:incoming_messages"),
"text": "Eingehende Nachrichten" + f" ({num_unread})"
if num_unread
else "",
"text": "Eingehende Nachrichten"
+ (f" ({num_unread})" if num_unread else ""),
}
)

View File

@ -1,5 +1,7 @@
{% extends "base.html" %}
{% load humanize %}
{% block title %}Helferdetails{% endblock %}
{% block content %}
@ -15,4 +17,43 @@
</a>
{% endfor %}
</div>
<h5 class="subtitle" id="history">Nachrichtenverlauf</h5>
{% for content, created_at, read, incoming in history %}
<div class="message{% if not read %} is-info{% endif %} mb-5 {% if incoming %}message-incoming{% else %}{% if not created_at %}is-warning{% else %}is-primary{% endif %} message-outgoing{% endif %}">
<div class="message-body">
<div class="is-flex is-flex-wrap-wrap">
{{ content }}
{% if created_at %}
<div class="has-text-right is-flex-grow-1">
<small>{{ created_at | naturaltime }}</small>
</div>
{% endif %}
</div>
</div>
</div>
{% endfor %}
<form action="{% url 'team:mark_as_read' helper.pk %}" id="markAsRead" method="POST">
{% csrf_token %}
</form>
<form id="sendMessage" method="POST">
{% csrf_token %}
{% for field in form %}
<div class="field">
<div class="control">
{{ field }}
</div>
{% for error in field.errors %}
<p class="help is-danger">{{ error }}</p>
{% endfor %}
</div>
{% endfor %}
<div class="field is-grouped is-grouped-right">
<div class="control">
<button class="button" form="markAsRead" type="submit">Alle als gelesen markieren</button>
</div>
<div class="control">
<button class="button is-link" form="sendMessage" type="submit">Senden</button>
</div>
</div>
</form>
{% endblock %}

View File

@ -0,0 +1,23 @@
{% extends "base.html" %}
{% load humanize %}
{% block title %}Nachricht von {{ message.sender }}{% endblock %}
{% block content %}
<h3 class="title">Nachricht von {{ message.sender }}{% if not message.read %} (ungelesen){% endif %}</h3>
<div class="display mb-5">
<p>{{ message.created_at | naturaltime }}</p>
</div>
<div class="message mb-5">
<div class="message-body">
{{ message.content }}
</div>
</div>
{% if not message.read %}
<form method="POST">
{% csrf_token %}
<button class="button is-info" type="submit">Als gelesen markieren</button>
</form>
{% endif %}
{% endblock %}

View File

@ -5,8 +5,9 @@
{% block title %}Sie haben {{ num_unread | apnumber }} neue Nachricht{{ num_unread | pluralize:"en" }}{% endblock %}
{% block content %}
<h3 class="title">Eingehende Nachrichten</h3>
{% for message in page %}
<a href="{% if message.from_helper %}{% url 'team:helper' message.from_helper.pk %}{% else %}{% url 'team:conversation' message.sender %}{% endif %}">
<a href="{% if message.from_helper %}{% url 'team:helper' message.from_helper.pk %}#history{% else %}{% url 'team:incoming_message' message.pk %}{% 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>

View File

@ -14,5 +14,6 @@ urlpatterns = [
path("checkin/<int:pk>", views.checkin, name="checkin"),
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"),
path("incoming/<int:pk>", views.incoming_message, name="incoming_message"),
path("incoming/mark_as_read/<int:pk>", views.mark_as_read, name="mark_as_read"),
]

View File

@ -5,11 +5,12 @@ from django.db.models.fields import DateTimeField
from django.db.models import F, Count, Q, ExpressionWrapper, Case, When
from .models import ShiftRegistration, Room, Shift, Helper, Message, IncomingMessage
from django.views.generic import DetailView, ListView
from django.views.generic.edit import FormMixin
from django.contrib.auth.mixins import LoginRequiredMixin
from django.contrib import messages
from django.db import models
from django.core.paginator import Paginator
from .forms import BulkMessage, HelperShift
from .forms import BulkMessage, HelperShift, HelperMessage
# Create your views here.
@ -136,9 +137,36 @@ def bulk_message(request):
return render(request, "bulk_message.html", context)
class HelperDetail(LoginRequiredMixin, DetailView):
class HelperDetail(FormMixin, LoginRequiredMixin, DetailView):
template_name = "helper_detail.html"
model = Helper
form_class = HelperMessage
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context["history"] = (
IncomingMessage.objects.filter(sender=self.object.phone)
.annotate(incoming=models.Value(True))
.values_list("content", "created_at", "read", "incoming")
.union(
self.object.message_set.annotate(
read=models.Value(True), incoming=models.Value(False)
).values_list("text", "sent_at", "read", "incoming")
)
.order_by(F("created_at").asc(nulls_last=True))
)
return context
def post(self, request, *args, **kwargs):
self.object = self.get_object()
form = self.get_form()
if form.is_valid():
Message(text=form.cleaned_data["message"], to=self.object).save()
return self.render_to_response(self.get_context_data(form=form))
class ShiftList(LoginRequiredMixin, ListView):
@ -212,5 +240,21 @@ def incoming_messages(request):
@login_required
def conversation(request, sender):
pass
def incoming_message(request, pk):
message = get_object_or_404(IncomingMessage, pk=pk)
if request.method == "POST":
message.read = True
message.save()
return render(request, "incoming_message.html", {"message": message})
@login_required
def mark_as_read(request, pk):
helper = get_object_or_404(Helper, pk=pk)
if request.method == "POST":
IncomingMessage.objects.filter(sender=helper.phone).update(read=True)
return redirect("team:helper", pk=pk)