feat(messages): delete group and delete individual messages
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
- Group owner can delete entire group (danger zone in manage panel) - Message author or group owner can delete individual messages (trash icon on hover) - CASCADE deletes attachments from disk Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
cda97c18bb
commit
d86e77aef0
@ -682,3 +682,68 @@ def group_edit(group_id):
|
||||
return redirect(url_for('.group_manage', group_id=group_id))
|
||||
finally:
|
||||
db.close()
|
||||
|
||||
|
||||
@bp.route('/wiadomosci/grupa/<int:group_id>/wiadomosc/<int:message_id>/usun', methods=['POST'])
|
||||
@login_required
|
||||
@member_required
|
||||
def group_delete_message(group_id, message_id):
|
||||
"""Usuń wiadomość (tylko autor lub owner grupy)"""
|
||||
db = SessionLocal()
|
||||
try:
|
||||
group, membership = _check_group_access(db, group_id, current_user.id)
|
||||
if not group:
|
||||
flash('Grupa nie istnieje lub nie masz dostępu.', 'error')
|
||||
return redirect(url_for('.messages_inbox'))
|
||||
|
||||
msg = db.query(GroupMessage).filter(
|
||||
GroupMessage.id == message_id,
|
||||
GroupMessage.group_id == group_id
|
||||
).first()
|
||||
|
||||
if not msg:
|
||||
flash('Wiadomość nie istnieje.', 'error')
|
||||
return redirect(url_for('.group_view', group_id=group_id))
|
||||
|
||||
# Only message author or group owner can delete
|
||||
if msg.sender_id != current_user.id and not membership.is_owner:
|
||||
flash('Nie masz uprawnień do usunięcia tej wiadomości.', 'error')
|
||||
return redirect(url_for('.group_view', group_id=group_id))
|
||||
|
||||
# Delete attachments from disk
|
||||
for att in msg.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(msg)
|
||||
db.commit()
|
||||
flash('Wiadomość usunięta.', 'success')
|
||||
return redirect(url_for('.group_view', group_id=group_id))
|
||||
finally:
|
||||
db.close()
|
||||
|
||||
|
||||
@bp.route('/wiadomosci/grupa/<int:group_id>/usun', methods=['POST'])
|
||||
@login_required
|
||||
@member_required
|
||||
def group_delete(group_id):
|
||||
"""Usuń grupę (tylko owner)"""
|
||||
db = SessionLocal()
|
||||
try:
|
||||
group, membership = _check_group_access(db, group_id, current_user.id)
|
||||
if not group or not membership.is_owner:
|
||||
flash('Tylko właściciel może usunąć grupę.', 'error')
|
||||
return redirect(url_for('.messages_inbox'))
|
||||
|
||||
group_name = group.name or group.display_name
|
||||
db.delete(group)
|
||||
db.commit()
|
||||
flash(f'Grupa "{group_name}" została usunięta.', 'success')
|
||||
return redirect(url_for('.messages_inbox'))
|
||||
finally:
|
||||
db.close()
|
||||
|
||||
@ -362,6 +362,15 @@
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary">Zapisz zmiany</button>
|
||||
</form>
|
||||
|
||||
<div style="margin-top: var(--spacing-xl); padding-top: var(--spacing-lg); border-top: 1px solid var(--border-color, #e5e7eb);">
|
||||
<h3 style="color: #dc2626; font-size: var(--font-size-sm); margin-bottom: var(--spacing-sm);">Strefa niebezpieczna</h3>
|
||||
<p style="font-size: var(--font-size-xs); color: var(--text-secondary); margin-bottom: var(--spacing-sm);">Usunięcie grupy jest nieodwracalne. Wszystkie wiadomości i załączniki zostaną usunięte.</p>
|
||||
<form method="POST" action="{{ url_for('messages.group_delete', group_id=group.id) }}" onsubmit="return confirm('Czy na pewno chcesz usunąć tę grupę? Wszystkie wiadomości zostaną usunięte. Tej operacji nie można cofnąć.');">
|
||||
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}">
|
||||
<button type="submit" class="btn" style="background: #dc2626; color: white; border: none; font-size: var(--font-size-sm);">Usuń grupę</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
|
||||
@ -226,6 +226,25 @@
|
||||
color: var(--text-secondary);
|
||||
}
|
||||
|
||||
.msg-delete-btn {
|
||||
background: none;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
font-size: 12px;
|
||||
opacity: 0;
|
||||
transition: opacity 0.15s;
|
||||
padding: 2px;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
.msg-header:hover .msg-delete-btn {
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
.msg-delete-btn:hover {
|
||||
opacity: 1 !important;
|
||||
}
|
||||
|
||||
.msg-content {
|
||||
background: var(--surface);
|
||||
border: 1px solid var(--border-color, #e5e7eb);
|
||||
@ -436,6 +455,12 @@
|
||||
<div class="msg-header">
|
||||
<span class="msg-sender">{% if msg.sender_id == current_user.id %}Ty{% else %}<a href="{{ url_for('public.user_profile', user_id=msg.sender_id) }}" style="color: inherit; text-decoration: none;" onmouseover="this.style.textDecoration='underline'" onmouseout="this.style.textDecoration='none'">{{ msg.sender.name or msg.sender.email.split('@')[0] }}</a>{% endif %}</span>
|
||||
<span class="msg-time">{{ msg.created_at.strftime('%d.%m.%Y %H:%M') }}</span>
|
||||
{% if msg.sender_id == current_user.id or membership.is_owner %}
|
||||
<form method="POST" action="{{ url_for('messages.group_delete_message', group_id=group.id, message_id=msg.id) }}" style="display:inline; margin-left: 4px;" onsubmit="return confirm('Usunąć tę wiadomość?');">
|
||||
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}">
|
||||
<button type="submit" class="msg-delete-btn" title="Usuń wiadomość">🗑</button>
|
||||
</form>
|
||||
{% endif %}
|
||||
</div>
|
||||
<div class="msg-content">{{ msg.content|linkify }}</div>
|
||||
{% if msg.attachments %}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user