Implement incoming_message view and show message history on helper page
This commit is contained in:
parent
e9e263d59d
commit
eb681d31b0
|
@ -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;
|
||||
|
|
|
@ -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"}),
|
||||
)
|
||||
|
|
|
@ -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 ""),
|
||||
}
|
||||
)
|
||||
|
||||
|
|
|
@ -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 %}
|
||||
|
|
|
@ -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 %}
|
|
@ -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>
|
||||
|
|
|
@ -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"),
|
||||
]
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue