feat(messages): delete 1:1 messages and threads from detail view
Some checks are pending
NordaBiz Tests / Unit & Integration Tests (push) Waiting to run
NordaBiz Tests / E2E Tests (Playwright) (push) Blocked by required conditions
NordaBiz Tests / Smoke Tests (Production) (push) Blocked by required conditions
NordaBiz Tests / Send Failure Notification (push) Blocked by required conditions
Some checks are pending
NordaBiz Tests / Unit & Integration Tests (push) Waiting to run
NordaBiz Tests / E2E Tests (Playwright) (push) Blocked by required conditions
NordaBiz Tests / Smoke Tests (Production) (push) Blocked by required conditions
NordaBiz Tests / Send Failure Notification (push) Blocked by required conditions
Trash icon in message detail header. Deletes message with all replies and attachments. Uses nordaConfirm() styled modal. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
c18f65e3f3
commit
0812ec0fb3
@ -260,6 +260,7 @@ def register_blueprints(app):
|
||||
'messages_send': 'messages.messages_send',
|
||||
'messages_view': 'messages.messages_view',
|
||||
'messages_reply': 'messages.messages_reply',
|
||||
'messages_delete': 'messages.messages_delete',
|
||||
'api_unread_count': 'messages.api_unread_count',
|
||||
'api_notifications': 'messages.api_notifications',
|
||||
'api_notification_mark_read': 'messages.api_notification_mark_read',
|
||||
|
||||
@ -427,6 +427,58 @@ def messages_view(message_id):
|
||||
db.close()
|
||||
|
||||
|
||||
@bp.route('/wiadomosci/<int:message_id>/usun', methods=['POST'])
|
||||
@login_required
|
||||
@member_required
|
||||
def messages_delete(message_id):
|
||||
"""Usuń wiadomość (nadawca lub odbiorca)"""
|
||||
db = SessionLocal()
|
||||
try:
|
||||
message = db.query(PrivateMessage).options(
|
||||
joinedload(PrivateMessage.attachments)
|
||||
).filter(PrivateMessage.id == message_id).first()
|
||||
|
||||
if not message:
|
||||
flash('Wiadomość nie istnieje.', 'error')
|
||||
return redirect(url_for('.messages_inbox'))
|
||||
|
||||
if message.sender_id != current_user.id and message.recipient_id != current_user.id:
|
||||
flash('Brak dostępu do tej wiadomości.', 'error')
|
||||
return redirect(url_for('.messages_inbox'))
|
||||
|
||||
# Delete attachments from disk
|
||||
import os
|
||||
from database import MessageAttachment
|
||||
for att in message.attachments:
|
||||
try:
|
||||
filepath = os.path.join('static', 'uploads', 'messages',
|
||||
att.created_at.strftime('%Y'), att.created_at.strftime('%m'), att.stored_filename)
|
||||
if os.path.exists(filepath):
|
||||
os.remove(filepath)
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
# Delete replies if this is root message
|
||||
replies = db.query(PrivateMessage).filter(PrivateMessage.parent_id == message_id).all()
|
||||
for reply in replies:
|
||||
for att in reply.attachments:
|
||||
try:
|
||||
filepath = os.path.join('static', 'uploads', 'messages',
|
||||
att.created_at.strftime('%Y'), att.created_at.strftime('%m'), att.stored_filename)
|
||||
if os.path.exists(filepath):
|
||||
os.remove(filepath)
|
||||
except Exception:
|
||||
pass
|
||||
db.delete(reply)
|
||||
|
||||
db.delete(message)
|
||||
db.commit()
|
||||
flash('Wiadomość usunięta.', 'success')
|
||||
return redirect(url_for('.messages_inbox'))
|
||||
finally:
|
||||
db.close()
|
||||
|
||||
|
||||
@bp.route('/api/messages/upload-image', methods=['POST'])
|
||||
@login_required
|
||||
@member_required
|
||||
|
||||
@ -495,8 +495,12 @@
|
||||
{% endif %}
|
||||
|
||||
<div class="message-card-header">
|
||||
<div class="message-subject-row">
|
||||
<div class="message-subject-row" style="display: flex; align-items: center; justify-content: space-between;">
|
||||
<div class="message-subject">{{ message.subject or '(brak tematu)' }}</div>
|
||||
<form method="POST" action="{{ url_for('messages.messages_delete', message_id=message.id) }}" style="margin: 0;" onsubmit="return nordaConfirm(this, '{% if thread %}Cały wątek ({{ thread|length }} wiadomości) zostanie trwale usunięty.{% else %}Wiadomość zostanie trwale usunięta.{% endif %}', {title: 'Usunąć {% if thread %}wątek{% else %}wiadomość{% endif %}?', icon: '🗑️', okText: 'Tak, usuń'});">
|
||||
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}">
|
||||
<button type="submit" title="Usuń {% if thread %}wątek{% else %}wiadomość{% endif %}" style="background: none; border: none; cursor: pointer; color: var(--text-secondary); font-size: 16px; padding: 4px 8px; border-radius: var(--radius); transition: var(--transition);" onmouseover="this.style.color='#dc2626'" onmouseout="this.style.color='var(--text-secondary)'">🗑</button>
|
||||
</form>
|
||||
</div>
|
||||
<div class="message-participants">
|
||||
<a href="{{ url_for('public.user_profile', user_id=message.sender_id) }}" class="participant-avatar {% if message.sender_id == current_user.id %}is-me{% endif %}" style="text-decoration: none; color: white;">
|
||||
|
||||
Loading…
Reference in New Issue
Block a user