Add staff-only all comments page and bump versions
All checks were successful
Build containers when image tags change / build-if-image-changed (., web, containers, main container, git.baumann.gr/adebaumann/vui) (push) Successful in 15s
Build containers when image tags change / build-if-image-changed (data-loader, loader, initContainers, init-container, git.baumann.gr/adebaumann/vui-data-loader) (push) Successful in 4s
SonarQube Scan / SonarQube Trigger (push) Successful in 47s
All checks were successful
Build containers when image tags change / build-if-image-changed (., web, containers, main container, git.baumann.gr/adebaumann/vui) (push) Successful in 15s
Build containers when image tags change / build-if-image-changed (data-loader, loader, initContainers, init-container, git.baumann.gr/adebaumann/vui-data-loader) (push) Successful in 4s
SonarQube Scan / SonarQube Trigger (push) Successful in 47s
- Add new "alle-kommentare" (all comments) view for staff users only - Allows staff to view and manage all user comments across the system - Grouped by document with user information displayed - Staff can delete any comment via the dedicated delete button - Restricts access via user_passes_test decorator - Create all_comments.html template - Based on user_comments template with added username field - Shows comment author, creation time, and edit time - Provides delete functionality for comment management - Update navigation menu - Add "Alle Kommentare" link in user dropdown menu - Link only visible to staff members - Add URL route for alle-kommentare page - Path: /dokumente/alle-kommentare/ - URL name: all_comments - Bump application versions - Update footer version from 0.965 to 0.966 - Update K8s deployment version from 0.917 to 0.918 - ArgoCD deployment already at 0.966 All existing tests pass (148 tests total)
This commit is contained in:
@@ -21,7 +21,7 @@ ENV PYTHONDONTWRITEBYTECODE=1
|
||||
ENV PYTHONUNBUFFERED=1
|
||||
USER appuser
|
||||
EXPOSE 8000
|
||||
RUN rm -rf /app/Dockerfile* \
|
||||
RUN rm -rvf /app/Dockerfile* \
|
||||
/app/README.md \
|
||||
/app/argocd \
|
||||
/app/k8s \
|
||||
@@ -31,6 +31,6 @@ RUN rm -rf /app/Dockerfile* \
|
||||
/app/node_modules \
|
||||
/app/*.json \
|
||||
/app/test_*.py && \
|
||||
python3 manage.py collectstatic
|
||||
python3 /app/manage.py collectstatic --noinput
|
||||
CMD ["gunicorn","--bind","0.0.0.0:8000","--workers","3","VorgabenUI.wsgi:application"]
|
||||
|
||||
|
||||
@@ -127,7 +127,7 @@ USE_TZ = True
|
||||
|
||||
STATIC_URL = '/static/'
|
||||
#STATIC_ROOT="/home/adebaumann/VorgabenUI/staticfiles/"
|
||||
STATIC_ROOT="/app/staticfiles/"
|
||||
STATIC_ROOT="staticfiles/"
|
||||
STATICFILES_DIRS= (
|
||||
os.path.join(BASE_DIR,"static"),
|
||||
)
|
||||
|
||||
@@ -25,7 +25,7 @@ spec:
|
||||
mountPath: /data
|
||||
containers:
|
||||
- name: web
|
||||
image: git.baumann.gr/adebaumann/vui:0.965
|
||||
image: git.baumann.gr/adebaumann/vui:0.966
|
||||
imagePullPolicy: Always
|
||||
ports:
|
||||
- containerPort: 8000
|
||||
|
||||
67
dokumente/templates/standards/all_comments.html
Normal file
67
dokumente/templates/standards/all_comments.html
Normal file
@@ -0,0 +1,67 @@
|
||||
{% extends "base.html" %}
|
||||
|
||||
{% block content %}
|
||||
<h1>Alle Kommentare</h1>
|
||||
|
||||
{% if total_comments == 0 %}
|
||||
<div class="alert alert-info">
|
||||
<p>Es gibt noch keine Kommentare zu Vorgaben.</p>
|
||||
<p><a href="{% url 'standard_list' %}">Zu den Standards</a></p>
|
||||
</div>
|
||||
{% else %}
|
||||
<p class="text-muted">Insgesamt {{ total_comments }} Kommentar{{ total_comments|pluralize:"e" }}</p>
|
||||
|
||||
{% for dokument, comments in comments_by_document.items %}
|
||||
<div class="panel panel-default" style="margin-top: 2rem;">
|
||||
<div class="panel-heading">
|
||||
<h2 style="margin: 0;">
|
||||
<a href="{% url 'standard_detail' nummer=dokument.nummer %}">
|
||||
{{ dokument.nummer }} – {{ dokument.name }}
|
||||
</a>
|
||||
</h2>
|
||||
<p style="margin: 0; color: #666; font-size: 0.9rem;">
|
||||
{{ comments|length }} Kommentar{{ comments|length|pluralize:"e" }}
|
||||
</p>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<div class="list-group">
|
||||
{% for comment in comments %}
|
||||
<div class="list-group-item" style="border-left: 3px solid #007bff; padding: 1rem;">
|
||||
<div style="display: flex; justify-content: space-between; align-items: flex-start;">
|
||||
<div style="flex: 1;">
|
||||
<h4 style="margin: 0 0 0.5rem 0;">
|
||||
<a href="{% url 'standard_detail' nummer=comment.vorgabe.dokument.nummer %}#{{ comment.vorgabe.Vorgabennummer }}">
|
||||
{{ comment.vorgabe.Vorgabennummer }}
|
||||
</a> {{ comment.vorgabe.titel }}
|
||||
</h4>
|
||||
<p style="margin: 0 0 0.75rem 0; color: #666; font-size: 0.9rem;">
|
||||
<strong>Benutzer:</strong> {{ comment.user.first_name }} {{ comment.user.last_name }}<br>
|
||||
<strong>Erstellt:</strong> {{ comment.created_at|date:"d.m.Y H:i" }}
|
||||
{% if comment.updated_at != comment.created_at %}
|
||||
<br>
|
||||
<strong>Bearbeitet:</strong> {{ comment.updated_at|date:"d.m.Y H:i" }}
|
||||
{% endif %}
|
||||
</p>
|
||||
</div>
|
||||
<form method="POST" action="{% url 'delete_vorgabe_comment' comment.id %}"
|
||||
style="display: inline; margin-left: 1rem;"
|
||||
onsubmit="return confirm('Sind Sie sicher, dass Sie diesen Kommentar löschen möchten?');">
|
||||
{% csrf_token %}
|
||||
<button type="submit" class="btn btn-sm btn-danger">Löschen</button>
|
||||
</form>
|
||||
</div>
|
||||
<div style="background: #f8f9fa; padding: 0.75rem; border-radius: 4px; margin-top: 0.5rem; white-space: pre-wrap; word-wrap: break-word;">
|
||||
{{ comment.text }}
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
|
||||
<div style="margin-top: 2rem; padding-top: 2rem; border-top: 1px solid #ddd;">
|
||||
<a href="{% url 'standard_list' %}" class="btn btn-default">Zu den Standards</a>
|
||||
</div>
|
||||
{% endblock %}
|
||||
@@ -5,6 +5,7 @@ urlpatterns = [
|
||||
path('', views.standard_list, name='standard_list'),
|
||||
path('unvollstaendig/', views.incomplete_vorgaben, name='incomplete_vorgaben'),
|
||||
path('meine-kommentare/', views.user_comments, name='user_comments'),
|
||||
path('alle-kommentare/', views.all_comments, name='all_comments'),
|
||||
path('<str:nummer>/', views.standard_detail, name='standard_detail'),
|
||||
path('<str:nummer>/history/<str:check_date>/', views.standard_detail),
|
||||
path('<str:nummer>/history/', views.standard_detail, {"check_date":"today"}, name='standard_history'),
|
||||
|
||||
@@ -392,3 +392,31 @@ def user_comments(request):
|
||||
'comments_by_document': comments_by_document,
|
||||
'total_comments': user_comments.count(),
|
||||
})
|
||||
|
||||
|
||||
@login_required
|
||||
@user_passes_test(is_staff_user)
|
||||
def all_comments(request):
|
||||
"""
|
||||
Display all comments from all users, grouped by document.
|
||||
Staff only.
|
||||
"""
|
||||
# Get all comments
|
||||
all_comments_qs = VorgabeComment.objects.select_related(
|
||||
'vorgabe', 'vorgabe__dokument', 'user'
|
||||
).order_by(
|
||||
'vorgabe__dokument__nummer', '-created_at'
|
||||
)
|
||||
|
||||
# Group comments by document
|
||||
comments_by_document = {}
|
||||
for comment in all_comments_qs:
|
||||
dokument = comment.vorgabe.dokument
|
||||
if dokument not in comments_by_document:
|
||||
comments_by_document[dokument] = []
|
||||
comments_by_document[dokument].append(comment)
|
||||
|
||||
return render(request, 'standards/all_comments.html', {
|
||||
'comments_by_document': comments_by_document,
|
||||
'total_comments': all_comments_qs.count(),
|
||||
})
|
||||
|
||||
@@ -24,8 +24,8 @@ spec:
|
||||
- name: data
|
||||
mountPath: /data
|
||||
containers:
|
||||
- name: web
|
||||
image: docker.io/adebaumann/vui:0.917
|
||||
- name: web
|
||||
image: docker.io/adebaumann/vui:0.918
|
||||
imagePullPolicy: Always
|
||||
ports:
|
||||
- containerPort: 8000
|
||||
|
||||
@@ -52,18 +52,21 @@
|
||||
<span class="caret" style="margin-left: 8px;"></span>
|
||||
</a>
|
||||
<ul class="dropdown-menu dropdown-menu-right" role="menu">
|
||||
<li><a href="{% url 'user_comments' %}">Meine Kommentare</a></li>
|
||||
<li><a href="{% url 'password_change' %}">Passwort ändern</a></li>
|
||||
<li class="divider"></li>
|
||||
<li>
|
||||
<form method="post" action="{% url 'logout' %}" style="display: inline;">
|
||||
{% csrf_token %}
|
||||
<button type="submit" style="background: none; border: none; color: inherit; padding: 3px 20px; width: 100%; text-align: left; cursor: pointer;">
|
||||
Abmelden
|
||||
</button>
|
||||
</form>
|
||||
</li>
|
||||
</ul>
|
||||
<li><a href="{% url 'user_comments' %}">Meine Kommentare</a></li>
|
||||
{% if user.is_staff %}
|
||||
<li><a href="{% url 'all_comments' %}">Alle Kommentare</a></li>
|
||||
{% endif %}
|
||||
<li><a href="{% url 'password_change' %}">Passwort ändern</a></li>
|
||||
<li class="divider"></li>
|
||||
<li>
|
||||
<form method="post" action="{% url 'logout' %}" style="display: inline;">
|
||||
{% csrf_token %}
|
||||
<button type="submit" style="background: none; border: none; color: inherit; padding: 3px 20px; width: 100%; text-align: left; cursor: pointer;">
|
||||
Abmelden
|
||||
</button>
|
||||
</form>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
{% else %}
|
||||
@@ -216,8 +219,8 @@
|
||||
</p>
|
||||
</div>
|
||||
<div class="col-sm-6 text-right">
|
||||
<p class="text-muted">Version {{ version|default:"0.965" }}</p>
|
||||
</div>
|
||||
<p class="text-muted">Version {{ version|default:"0.966" }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
Reference in New Issue
Block a user