From 6d959ac253f54e545ef714a35c6d1a02583b57b8 Mon Sep 17 00:00:00 2001 From: Kobe Date: Thu, 29 May 2025 14:45:52 +0200 Subject: [PATCH] Revert "Added events system" This reverts commit f00d569db39d6075cdff3047ca7be203ec9770e5. --- __pycache__/models.cpython-313.pyc | Bin 20138 -> 20607 bytes app.py | 1 - models.py | 41 ++- routes/__pycache__/auth.cpython-313.pyc | Bin 7078 -> 6359 bytes .../__pycache__/conversations.cpython-313.pyc | Bin 21482 -> 20141 bytes routes/__pycache__/main.cpython-313.pyc | Bin 41967 -> 35731 bytes routes/auth.py | 29 -- routes/conversations.py | 51 +--- routes/main.py | 171 +---------- static/js/events.js | 272 ------------------ static/js/file-grid.js | 85 ++---- static/js/room-members.js | 98 +------ static/js/rooms-list.js | 133 --------- templates/settings/settings.html | 14 +- templates/settings/tabs/events.html | 165 ----------- templates/starred/starred.html | 89 ------ templates/trash/trash.html | 62 ---- utils/helpers.py => utils.py | 36 +++ utils/__init__.py | 18 -- utils/__pycache__/__init__.cpython-313.pyc | Bin 581 -> 0 bytes .../__pycache__/event_logger.cpython-313.pyc | Bin 5535 -> 0 bytes utils/__pycache__/helpers.cpython-313.pyc | Bin 1917 -> 0 bytes utils/__pycache__/permissions.cpython-313.pyc | Bin 1163 -> 0 bytes utils/permissions.py | 35 --- 24 files changed, 114 insertions(+), 1186 deletions(-) delete mode 100644 static/js/events.js delete mode 100644 templates/settings/tabs/events.html rename utils/helpers.py => utils.py (54%) delete mode 100644 utils/__init__.py delete mode 100644 utils/__pycache__/__init__.cpython-313.pyc delete mode 100644 utils/__pycache__/event_logger.cpython-313.pyc delete mode 100644 utils/__pycache__/helpers.cpython-313.pyc delete mode 100644 utils/__pycache__/permissions.cpython-313.pyc delete mode 100644 utils/permissions.py diff --git a/__pycache__/models.cpython-313.pyc b/__pycache__/models.cpython-313.pyc index bc5267f62d72eaed0b0e2a9a349af4880392617a..19e3c6de6ae7a5981dfccd6cd4a48ac33ee60c4e 100644 GIT binary patch delta 1218 zcmZva&rj1}7{^;&h_GzaA)DLS7(av|QH%+}#2-mn-@(S(lD-`rmr7q@$-0rZ0}mdy z#Kho9lb%gHdGKcVGra6((-R&|JdlV7;z8fOdpm}qX`c4;Jl}qwr%(I&1ON9UAN~~z zjdJ8zS$nj1vh*dqpXZP4cD^a37EoZIDs=TjVECSXW=BC+RZLZ*+27l z+ra}1;pz@XdJDNdIM_EXz(956RdBOu_GJ`&83iVbP%x4CoS5o{;YJ4&7@5sOZVxJ(;suDH47`e}C{kZW!Ix2B zvIqqUNUOwD5JfjSm{5VFYyme$bDKbwiqL>XMXvf*g<=^HC@X^KhA4>2woEbDLpBWs z707}F+z|@YxpxaSL3MljitK@%D9m0XJ?zCoq8-mG@)l5`pn07KMonH-U?Ybm0HLr3 z{0;P(P2Oj=hnTMyG)>5_OF-7>IugOnUU zcalpNF|*PQET){Pr`0pv;oYa3R+i6G3YK|l*u_N0lYbO3I zfH)>31T!1T%+5w7mdIjZ$qJ}thRd@ftkb*i_r9m^?&QB8(8qTue=Z1Fj(snT-ND1WupW0dd2q=!BtjG8i*$ukS>^?_Q_XeQ_vsO>Ec(ZnaGd z8&M9hd)SmL9Od@g3bwn4iY_%1XkrC3M*yd(A8X+8fCe@#-M~=>NY#(l2?o|Am7*4V zp`q)l-7ql310;#DlN_7@r=z#EC<{`-(h;U&Ypb4&^C~t?sfBG5YgSa0EK6$0D%1A* zQuNnGnO5Zdp3DC76K-+2I_oU1+?X9KN;hX}tN{P_inW=tC|sMhV|S(Kj$Eq6JqQrD z&(f7eTwz??{+6!Hzsj8yTF%9TODJ{D(K||jHt2h$iYoN8qGbz+' class EventType(Enum): + # User events USER_LOGIN = 'user_login' USER_LOGOUT = 'user_logout' - USER_REGISTER = 'user_register' + USER_CREATE = 'user_create' USER_UPDATE = 'user_update' + USER_DELETE = 'user_delete' + + # Room events + ROOM_CREATE = 'room_create' + ROOM_UPDATE = 'room_update' + ROOM_DELETE = 'room_delete' + ROOM_MEMBER_ADD = 'room_member_add' + ROOM_MEMBER_REMOVE = 'room_member_remove' + ROOM_PERMISSION_UPDATE = 'room_permission_update' + + # File events FILE_UPLOAD = 'file_upload' - FILE_DELETE = 'file_delete' FILE_DOWNLOAD = 'file_download' - FILE_RESTORE = 'file_restore' - FILE_MOVE = 'file_move' + FILE_DELETE = 'file_delete' FILE_RENAME = 'file_rename' + FILE_MOVE = 'file_move' FILE_STAR = 'file_star' FILE_UNSTAR = 'file_unstar' - ROOM_CREATE = 'room_create' - ROOM_DELETE = 'room_delete' - ROOM_UPDATE = 'room_update' - ROOM_JOIN = 'room_join' - ROOM_LEAVE = 'room_leave' + + # Conversation events CONVERSATION_CREATE = 'conversation_create' + CONVERSATION_UPDATE = 'conversation_update' CONVERSATION_DELETE = 'conversation_delete' - MESSAGE_SENT = 'message_sent' - ATTACHMENT_DOWNLOAD = 'attachment_download' + CONVERSATION_MEMBER_ADD = 'conversation_member_add' + CONVERSATION_MEMBER_REMOVE = 'conversation_member_remove' + + # Message events + MESSAGE_CREATE = 'message_create' + MESSAGE_UPDATE = 'message_update' + MESSAGE_DELETE = 'message_delete' + MESSAGE_ATTACHMENT_ADD = 'message_attachment_add' + MESSAGE_ATTACHMENT_REMOVE = 'message_attachment_remove' + + # Settings events + SETTINGS_UPDATE = 'settings_update' class Event(db.Model): __tablename__ = 'events' diff --git a/routes/__pycache__/auth.cpython-313.pyc b/routes/__pycache__/auth.cpython-313.pyc index 76dea33a6a83b3cfae1c2a6560537ad9ac63ec02..3792ef580305a6f27c6b6e6256f3aab83f7c272b 100644 GIT binary patch delta 1323 zcmZvcO>7%Q6vt#tw9Hxk-aRX^e5{ttzvMtCh0r{%Sy=QJrnShyr}M$UU}W$mkL?P>a|K)vv> zIIk!82A1S-1deisS@1|aB&GR8hNNeRrrOh<5eg4L70xfF8@!(l{s!inclJ|l?)+s7T@KLQmCZCO*Ku!@SAGDzfnK@5;CDIn=}IND{l=w^(0a+(4KvS*hcYD zXt`2f$yY1R(&B1`RaqAPQ4Z4_WPGnj2YDdV5eC9UMBxjcr9@Z&CkNn;Zz>lX3eH1YWXZ&eu!MpyP9Oe!u2j$2c@X&uz=*n<8P^Br@4p{EHKkR?^C7|+; z?GvgXz%{KfhRNJfQu`hfDzX9YWmyCs+EJQLjjdFcYrW%b_*=`yhWN^5wbE=Xhtsp}RmU(u$AIC-0r{oI@&()6dobpg5nhA`aSV}13?o#;al{B>6uu3Q z7Tm)0*8~sh-RxOzb(EFbr3JjPgLTZ{;KIm9o{=%JbD~|2SXBHYcmQtbhk2!b*0Z^j zeC0DTx7STV3Ve8UhXr?y!6P%=bPjS{ zC4b4pXMUn?X|d0}H-ek-W1CujL&>ug*k;ykQkCnMi!&1_QPkr!twadiHlJ&MZ?-7R z7(S?bHMkcwX#h2u*w<>XuW@RTE6#|Wld&~iT&uARd>0#{18_fnn(;N7shhb$k47v`3PGN(BrW@1oV6d>k~sDIMC9j2%IchH>3Qq`DqH z?J9dg8^%COYQ4991yjA`MjO)PlW6T_y5r#vxA#R`hhG!#%rg87axcnWL93?=ZgrH& x<<)BQLhU3w%crO}2fwqfNGaVWQ@@j`Z8Eb-X10m-fLMQeyfn3|zfEZ`|9@Mp6+i$0 delta 1959 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 ym$QQDbT857{YkuPZ delta 5083 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 LnuFv3;dcKAkmiIh diff --git a/routes/__pycache__/main.cpython-313.pyc b/routes/__pycache__/main.cpython-313.pyc index 21b9a7e68a7ae5de7c38f4e04f5455b4789be60d..28d31bbb015e78197884db5123a30176c2bd1780 100644 GIT binary patch delta 4112 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 diff --git a/routes/auth.py b/routes/auth.py index 9591b6b..15fab4e 100644 --- a/routes/auth.py +++ b/routes/auth.py @@ -2,8 +2,6 @@ from flask import render_template, request, flash, redirect, url_for from flask_login import login_user, logout_user, login_required, current_user from models import db, User from functools import wraps -from utils.event_logger import log_event -from models import EventType def require_password_change(f): @wraps(f) @@ -33,13 +31,6 @@ def init_routes(auth_bp): login_user(user, remember=remember) - # Log successful login - log_event( - event_type=EventType.USER_LOGIN, - user_id=user.id, - details={'remember': remember} - ) - # Check if user is using default password if password == 'changeme': flash('Please change your password before continuing.', 'warning') @@ -78,13 +69,6 @@ def init_routes(auth_bp): db.session.add(new_user) db.session.commit() - # Log user creation - log_event( - event_type=EventType.USER_CREATE, - user_id=new_user.id, - details={'email': email, 'username': username} - ) - login_user(new_user) return redirect(url_for('main.dashboard')) @@ -93,11 +77,6 @@ def init_routes(auth_bp): @auth_bp.route('/logout') @login_required def logout(): - # Log logout before actually logging out - log_event( - event_type=EventType.USER_LOGOUT, - user_id=current_user.id - ) logout_user() return redirect(url_for('auth.login')) @@ -119,14 +98,6 @@ def init_routes(auth_bp): current_user.set_password(new_password) db.session.commit() - - # Log password change - log_event( - event_type=EventType.USER_UPDATE, - user_id=current_user.id, - details={'action': 'password_change'} - ) - flash('Password changed successfully!', 'success') return redirect(url_for('main.dashboard')) diff --git a/routes/conversations.py b/routes/conversations.py index 3eca36c..3bcdbe9 100644 --- a/routes/conversations.py +++ b/routes/conversations.py @@ -1,9 +1,8 @@ from flask import Blueprint, render_template, redirect, url_for, flash, request, jsonify, send_file from flask_login import login_required, current_user -from models import db, Conversation, User, Message, MessageAttachment, EventType +from models import db, Conversation, User, Message, MessageAttachment from forms import ConversationForm from routes.auth import require_password_change -from utils.event_logger import log_event import os from werkzeug.utils import secure_filename from datetime import datetime @@ -85,17 +84,6 @@ def create_conversation(): db.session.add(conversation) db.session.commit() - # Log conversation creation - log_event( - event_type=EventType.CONVERSATION_CREATE, - user_id=current_user.id, - details={ - 'conversation_id': conversation.id, - 'conversation_name': conversation.name, - 'member_count': len(conversation.members) - } - ) - flash('Conversation created successfully!', 'success') return redirect(url_for('conversations.conversations')) return render_template('conversations/create_conversation.html', form=form) @@ -239,18 +227,6 @@ def delete_conversation(conversation_id): conversation = Conversation.query.get_or_404(conversation_id) - # Log conversation deletion before deleting - log_event( - event_type=EventType.CONVERSATION_DELETE, - user_id=current_user.id, - details={ - 'conversation_id': conversation_id, - 'conversation_name': conversation.name, - 'message_count': len(conversation.messages), - 'member_count': len(conversation.members) - } - ) - # Delete all messages in the conversation Message.query.filter_by(conversation_id=conversation_id).delete() @@ -348,18 +324,6 @@ def send_message(conversation_id): db.session.commit() - # Log message sent - log_event( - event_type=EventType.MESSAGE_SENT, - user_id=current_user.id, - details={ - 'conversation_id': conversation_id, - 'message_id': message.id, - 'has_attachments': len(attachments) > 0, - 'attachment_count': len(attachments) - } - ) - # Prepare message data for response message_data = { 'id': message.id, @@ -394,19 +358,6 @@ def download_attachment(message_id, attachment_index): try: attachment = message.attachments[attachment_index] - - # Log attachment download - log_event( - event_type=EventType.ATTACHMENT_DOWNLOAD, - user_id=current_user.id, - details={ - 'conversation_id': conversation.id, - 'message_id': message_id, - 'attachment_name': attachment.name, - 'attachment_size': attachment.size - } - ) - return send_file( attachment.path, as_attachment=True, diff --git a/routes/main.py b/routes/main.py index 67159fd..9038adf 100644 --- a/routes/main.py +++ b/routes/main.py @@ -1,8 +1,7 @@ -from flask import render_template, Blueprint, redirect, url_for, request, flash, Response, jsonify +from flask import render_template, Blueprint, redirect, url_for, request, flash, Response from flask_login import current_user, login_required -from models import User, db, Room, RoomFile, RoomMemberPermission, SiteSettings, Event, EventType +from models import User, db, Room, RoomFile, RoomMemberPermission, SiteSettings from routes.auth import require_password_change -from utils.event_logger import log_event import os from werkzeug.utils import secure_filename from sqlalchemy import func, case, literal_column, text @@ -280,14 +279,6 @@ def init_routes(main_bp): os.remove(old_picture_path) current_user.profile_picture = None db.session.commit() - - # Log profile picture removal - log_event( - event_type=EventType.USER_UPDATE, - user_id=current_user.id, - details={'action': 'remove_profile_picture'} - ) - flash('Profile picture removed successfully!', 'success') return redirect(url_for('main.profile')) @@ -298,10 +289,6 @@ def init_routes(main_bp): if existing_user: flash('A user with this email already exists.', 'error') return render_template('profile/profile.html') - - # Track changes for event logging - changes = {} - # Handle profile picture upload file = request.files.get('profile_picture') if file and file.filename: @@ -309,31 +296,14 @@ def init_routes(main_bp): file_path = os.path.join(UPLOAD_FOLDER, filename) file.save(file_path) current_user.profile_picture = filename - changes['profile_picture'] = True - # Update user information - if current_user.username != request.form.get('first_name'): - current_user.username = request.form.get('first_name') - changes['username'] = True - if current_user.last_name != request.form.get('last_name'): - current_user.last_name = request.form.get('last_name') - changes['last_name'] = True - if current_user.email != new_email: - current_user.email = new_email - changes['email'] = True - if current_user.phone != request.form.get('phone'): - current_user.phone = request.form.get('phone') - changes['phone'] = True - if current_user.company != request.form.get('company'): - current_user.company = request.form.get('company') - changes['company'] = True - if current_user.position != request.form.get('position'): - current_user.position = request.form.get('position') - changes['position'] = True - if current_user.notes != request.form.get('notes'): - current_user.notes = request.form.get('notes') - changes['notes'] = True - + current_user.username = request.form.get('first_name') + current_user.last_name = request.form.get('last_name') + current_user.email = new_email + current_user.phone = request.form.get('phone') + current_user.company = request.form.get('company') + current_user.position = request.form.get('position') + current_user.notes = request.form.get('notes') # Handle password change if provided new_password = request.form.get('new_password') confirm_password = request.form.get('confirm_password') @@ -342,20 +312,9 @@ def init_routes(main_bp): flash('Passwords do not match.', 'error') return render_template('profile/profile.html') current_user.set_password(new_password) - changes['password'] = True flash('Password updated successfully.', 'success') - try: db.session.commit() - - # Log profile update if any changes were made - if changes: - log_event( - event_type=EventType.USER_UPDATE, - user_id=current_user.id, - details={'changes': changes} - ) - flash('Profile updated successfully!', 'success') except Exception as e: db.session.rollback() @@ -396,18 +355,11 @@ def init_routes(main_bp): site_settings = SiteSettings.get_settings() active_tab = request.args.get('tab', 'colors') - - # Get events for the events tab - events = [] - if active_tab == 'events': - events = Event.query.order_by(Event.timestamp.desc()).limit(50).all() - return render_template('settings/settings.html', primary_color=site_settings.primary_color, secondary_color=site_settings.secondary_color, active_tab=active_tab, - site_settings=site_settings, - events=events) + site_settings=site_settings) @main_bp.route('/settings/colors', methods=['POST']) @login_required @@ -578,105 +530,4 @@ def init_routes(main_bp): logger.info(f"[Dynamic Colors] Generated CSS with primary color: {primary_color}") logger.info(f"[Dynamic Colors] Cache version: {site_settings.updated_at.timestamp()}") - return Response(css, mimetype='text/css') - - @main_bp.route('/api/events') - @login_required - def get_events(): - if not current_user.is_admin: - return jsonify({'success': False, 'error': 'Unauthorized'}), 403 - - # Get filter parameters - page = request.args.get('page', 1, type=int) - event_type = request.args.get('eventType') - date_range = request.args.get('dateRange', '24h') - user_id = request.args.get('userId') - - # Build query - query = Event.query - - # Apply filters - if event_type: - query = query.filter_by(event_type=event_type) - if user_id: - query = query.filter_by(user_id=user_id) - - # Apply date range filter - if date_range != 'all': - now = datetime.utcnow() - if date_range == '24h': - start_date = now - timedelta(days=1) - elif date_range == '7d': - start_date = now - timedelta(days=7) - elif date_range == '30d': - start_date = now - timedelta(days=30) - query = query.filter(Event.timestamp >= start_date) - - # Get total count for pagination - total_count = query.count() - per_page = 50 - total_pages = (total_count + per_page - 1) // per_page - - # Get paginated results - events = query.order_by(Event.timestamp.desc())\ - .offset((page - 1) * per_page)\ - .limit(per_page)\ - .all() - - return jsonify({ - 'success': True, - 'events': [{ - 'id': event.id, - 'event_type': event.event_type, - 'timestamp': event.timestamp.isoformat(), - 'user': { - 'id': event.user.id, - 'username': event.user.username, - 'last_name': event.user.last_name or '' - }, - 'ip_address': event.ip_address, - 'details': event.details - } for event in events], - 'total_pages': total_pages - }) - - @main_bp.route('/api/events/') - @login_required - def get_event_details(event_id): - if not current_user.is_admin: - return jsonify({'success': False, 'error': 'Unauthorized'}), 403 - - event = Event.query.get_or_404(event_id) - - return jsonify({ - 'success': True, - 'event': { - 'id': event.id, - 'event_type': event.event_type, - 'timestamp': event.timestamp.isoformat(), - 'user': { - 'id': event.user.id, - 'username': event.user.username - }, - 'ip_address': event.ip_address, - 'user_agent': event.user_agent, - 'details': event.details - } - }) - - @main_bp.route('/api/users') - @login_required - def get_users(): - if not current_user.is_admin: - return jsonify({'success': False, 'error': 'Unauthorized'}), 403 - - users = User.query.order_by(User.username).all() - - return jsonify({ - 'success': True, - 'users': [{ - 'id': user.id, - 'username': user.username, - 'last_name': user.last_name or '' - } for user in users] - }) \ No newline at end of file + return Response(css, mimetype='text/css') \ No newline at end of file diff --git a/static/js/events.js b/static/js/events.js deleted file mode 100644 index e1e1147..0000000 --- a/static/js/events.js +++ /dev/null @@ -1,272 +0,0 @@ -/** - * @fileoverview Manages the events page functionality. - * This file handles event filtering, pagination, and modal interactions. - */ - -document.addEventListener('DOMContentLoaded', function() { - // Elements - const eventTypeFilter = document.getElementById('eventTypeFilter'); - const dateRangeFilter = document.getElementById('dateRangeFilter'); - const userFilter = document.getElementById('userFilter'); - const applyFiltersBtn = document.getElementById('applyFilters'); - const eventsTableBody = document.getElementById('eventsTableBody'); - const prevPageBtn = document.getElementById('prevPage'); - const nextPageBtn = document.getElementById('nextPage'); - const currentPageSpan = document.getElementById('currentPage'); - const totalPagesSpan = document.getElementById('totalPages'); - const eventDetailsModal = document.getElementById('eventDetailsModal'); - const eventDetailsContent = document.getElementById('eventDetailsContent'); - - // State - let currentPage = 1; - let totalPages = 1; - let currentFilters = { - eventType: '', - dateRange: '24h', - userId: '' - }; - - /** - * Loads events based on current filters and page - */ - async function loadEvents() { - try { - const response = await fetch(`/api/events?page=${currentPage}&${new URLSearchParams(currentFilters)}`); - const data = await response.json(); - - if (data.success) { - renderEvents(data.events); - updatePagination(data.total_pages); - } else { - console.error('Failed to load events:', data.error); - } - } catch (error) { - console.error('Error loading events:', error); - } - } - - /** - * Renders events in the table - */ - function renderEvents(events) { - if (!Array.isArray(events)) { - console.error('Invalid events data received:', events); - return; - } - - const eventRows = events.map(event => { - if (!event || typeof event !== 'object') { - console.error('Invalid event data:', event); - return ''; - } - - // Determine badge color and text based on event type - let badgeClass = 'bg-secondary'; - let eventText = event.event_type || 'Unknown Event'; - - switch(event.event_type) { - case 'user_login': - badgeClass = 'bg-success'; - eventText = 'User Login'; - break; - case 'user_logout': - badgeClass = 'bg-secondary'; - eventText = 'User Logout'; - break; - case 'user_register': - badgeClass = 'bg-info'; - eventText = 'User Registration'; - break; - case 'user_update': - badgeClass = 'bg-primary'; - eventText = 'User Update'; - break; - case 'file_upload': - badgeClass = 'bg-success'; - eventText = 'File Upload'; - break; - case 'file_delete': - badgeClass = 'bg-danger'; - eventText = 'File Delete'; - break; - case 'file_download': - badgeClass = 'bg-info'; - eventText = 'File Download'; - break; - case 'file_restore': - badgeClass = 'bg-warning'; - eventText = 'File Restore'; - break; - case 'file_move': - badgeClass = 'bg-primary'; - eventText = 'File Move'; - break; - case 'file_rename': - badgeClass = 'bg-info'; - eventText = 'File Rename'; - break; - case 'file_star': - badgeClass = 'bg-warning'; - eventText = 'File Star'; - break; - case 'file_unstar': - badgeClass = 'bg-secondary'; - eventText = 'File Unstar'; - break; - case 'room_create': - badgeClass = 'bg-success'; - eventText = 'Room Create'; - break; - case 'room_delete': - badgeClass = 'bg-danger'; - eventText = 'Room Delete'; - break; - case 'room_update': - badgeClass = 'bg-primary'; - eventText = 'Room Update'; - break; - case 'room_join': - badgeClass = 'bg-info'; - eventText = 'Room Join'; - break; - case 'room_leave': - badgeClass = 'bg-secondary'; - eventText = 'Room Leave'; - break; - case 'conversation_create': - badgeClass = 'bg-success'; - eventText = 'Conversation Create'; - break; - case 'conversation_delete': - badgeClass = 'bg-danger'; - eventText = 'Conversation Delete'; - break; - case 'message_sent': - badgeClass = 'bg-primary'; - eventText = 'Message Sent'; - break; - case 'attachment_download': - badgeClass = 'bg-info'; - eventText = 'Attachment Download'; - break; - } - - const timestamp = event.timestamp ? new Date(event.timestamp).toLocaleString() : '-'; - const username = event.user?.username || 'Unknown User'; - const lastName = event.user?.last_name || ''; - const eventId = event.id || ''; - const ipAddress = event.ip_address || '-'; - - return ` - - ${timestamp} - ${eventText} - ${username} ${lastName} - - - - ${ipAddress} - - `; - }).join(''); - - eventsTableBody.innerHTML = eventRows; - - // Add event listeners to detail buttons - document.querySelectorAll('[data-event-id]').forEach(button => { - button.addEventListener('click', () => { - const eventId = button.dataset.eventId; - if (eventId) { - showEventDetails(eventId); - } - }); - }); - } - - /** - * Updates pagination controls - */ - function updatePagination(total) { - totalPages = total; - currentPageSpan.textContent = currentPage; - totalPagesSpan.textContent = totalPages; - - prevPageBtn.classList.toggle('disabled', currentPage === 1); - nextPageBtn.classList.toggle('disabled', currentPage === totalPages); - } - - /** - * Shows event details in modal - */ - async function showEventDetails(eventId) { - try { - const response = await fetch(`/api/events/${eventId}`); - const data = await response.json(); - - if (data.success) { - const event = data.event; - eventDetailsContent.textContent = JSON.stringify(event.details, null, 2); - } else { - console.error('Failed to load event details:', data.error); - } - } catch (error) { - console.error('Error loading event details:', error); - } - } - - /** - * Loads users for the user filter - */ - async function loadUsers() { - try { - const response = await fetch('/api/users'); - const data = await response.json(); - - const userFilter = document.getElementById('userFilter'); - userFilter.innerHTML = ''; - - data.users.forEach(user => { - const option = document.createElement('option'); - option.value = user.id; - option.textContent = `${user.username} ${user.last_name || ''}`.trim(); - userFilter.appendChild(option); - }); - } catch (error) { - console.error('Error loading users:', error); - } - } - - // Event Listeners - applyFiltersBtn.addEventListener('click', () => { - currentFilters = { - eventType: eventTypeFilter.value, - dateRange: dateRangeFilter.value, - userId: userFilter.value - }; - currentPage = 1; - loadEvents(); - }); - - prevPageBtn.addEventListener('click', () => { - if (currentPage > 1) { - currentPage--; - loadEvents(); - } - }); - - nextPageBtn.addEventListener('click', () => { - if (currentPage < totalPages) { - currentPage++; - loadEvents(); - } - }); - - // Initialize - loadUsers(); - loadEvents(); -}); \ No newline at end of file diff --git a/static/js/file-grid.js b/static/js/file-grid.js index 95a99e2..36ffc80 100644 --- a/static/js/file-grid.js +++ b/static/js/file-grid.js @@ -354,24 +354,6 @@ function toggleStar(filename, path = '', roomId) { .then(r => r.json()) .then(res => { if (res.success) { - // Log the star/unstar event - fetch('/api/events/log', { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - 'X-CSRFToken': csrfToken - }, - body: JSON.stringify({ - event_type: res.starred ? 'file_star' : 'file_unstar', - details: { - filename: filename, - path: path, - room_id: roomId, - timestamp: new Date().toISOString() - } - }) - }); - // Remove the file from the current view since it's no longer starred currentFiles = currentFiles.filter(f => !(f.name === filename && f.path === path && f.room_id === roomId)); renderFiles(currentFiles); @@ -412,24 +394,6 @@ function restoreFile(filename, path = '', roomId) { .then(r => r.json()) .then(res => { if (res.success) { - // Log the restore event - fetch('/api/events/log', { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - 'X-CSRFToken': csrfToken - }, - body: JSON.stringify({ - event_type: 'file_restore', - details: { - filename: filename, - path: path, - room_id: roomId, - timestamp: new Date().toISOString() - } - }) - }); - // Remove the file from the current view since it's been restored currentFiles = currentFiles.filter(f => !(f.name === filename && f.path === path && f.room_id === roomId)); renderFiles(currentFiles); @@ -470,7 +434,7 @@ function permanentDeleteFile() { return; } - fetch(`/api/rooms/${roomId}/delete_permanent`, { + fetch(`/api/rooms/${roomId}/delete-permanent`, { method: 'POST', headers: { 'Content-Type': 'application/json', @@ -481,40 +445,39 @@ function permanentDeleteFile() { path: path }) }) - .then(r => r.json()) + .then(response => { + if (!response.ok) { + throw new Error(`HTTP error! status: ${response.status}`); + } + // Check if the response is empty + const contentType = response.headers.get('content-type'); + if (contentType && contentType.includes('application/json')) { + return response.json(); + } + return { success: true }; // If no JSON response, assume success + }) .then(res => { if (res.success) { - // Log the permanent delete event - fetch('/api/events/log', { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - 'X-CSRFToken': csrfToken - }, - body: JSON.stringify({ - event_type: 'file_delete_permanent', - details: { - filename: filename, - path: path, - room_id: roomId, - timestamp: new Date().toISOString() - } - }) - }); - - // Remove the file from the current view + // Remove the file from the current view since it's been deleted currentFiles = currentFiles.filter(f => !(f.name === filename && f.path === path && f.room_id === roomId)); renderFiles(currentFiles); - // Close the modal const modal = bootstrap.Modal.getInstance(document.getElementById('permanentDeleteModal')); - modal.hide(); + if (modal) { + modal.hide(); + } } else { - console.error('Failed to delete file permanently:', res.error); + console.error('Failed to delete file:', res.error || 'Unknown error'); } }) .catch(error => { - console.error('Error deleting file permanently:', error); + console.error('Error deleting file:', error); + // Show error to user + const modal = bootstrap.Modal.getInstance(document.getElementById('permanentDeleteModal')); + if (modal) { + modal.hide(); + } + // You might want to show an error message to the user here }); } diff --git a/static/js/room-members.js b/static/js/room-members.js index 49ef5bf..198174c 100644 --- a/static/js/room-members.js +++ b/static/js/room-members.js @@ -13,95 +13,19 @@ * - Auto-save functionality for permission changes * @function */ -document.addEventListener('DOMContentLoaded', function() { - // Initialize Select2 +$(document).ready(function() { + // Initialize Select2 for user selection $('.select2').select2({ - theme: 'bootstrap-5' + theme: 'bootstrap-5', + width: '100%', + placeholder: 'Search for a user...', + allowClear: true }); - - // Log when a member is added to the room - const addMemberForm = document.querySelector('form[action*="/add_member"]'); - if (addMemberForm) { - addMemberForm.addEventListener('submit', function(e) { - const formData = new FormData(this); - const userId = formData.get('user_id'); - const roomId = this.action.split('/rooms/')[1].split('/add_member')[0]; - - fetch('/api/events/log', { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - 'X-CSRFToken': document.querySelector('meta[name="csrf-token"]').getAttribute('content') - }, - body: JSON.stringify({ - event_type: 'room_join', - details: { - room_id: roomId, - user_id: userId, - timestamp: new Date().toISOString() - } - }) - }); - }); - } - - // Log when a member is removed from the room - const removeMemberForms = document.querySelectorAll('form[action*="/remove_member"]'); - removeMemberForms.forEach(form => { - form.addEventListener('submit', function(e) { - const roomId = this.action.split('/rooms/')[1].split('/remove_member')[0]; - const userId = this.action.split('/users/')[1]; - - fetch('/api/events/log', { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - 'X-CSRFToken': document.querySelector('meta[name="csrf-token"]').getAttribute('content') - }, - body: JSON.stringify({ - event_type: 'room_leave', - details: { - room_id: roomId, - user_id: userId, - timestamp: new Date().toISOString() - } - }) - }); - }); - }); - - // Log when member permissions are updated - const permissionForms = document.querySelectorAll('.auto-save-perms-form'); - permissionForms.forEach(form => { - form.addEventListener('change', function(e) { - const roomId = this.action.split('/rooms/')[1].split('/update_member_permissions')[0]; - const userId = this.action.split('/users/')[1]; - const formData = new FormData(this); - - fetch('/api/events/log', { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - 'X-CSRFToken': document.querySelector('meta[name="csrf-token"]').getAttribute('content') - }, - body: JSON.stringify({ - event_type: 'room_member_permissions_update', - details: { - room_id: roomId, - user_id: userId, - permissions: { - can_view: formData.get('can_view') === '1', - can_download: formData.get('can_download') === 'on', - can_upload: formData.get('can_upload') === 'on', - can_delete: formData.get('can_delete') === 'on', - can_rename: formData.get('can_rename') === 'on', - can_move: formData.get('can_move') === 'on', - can_share: formData.get('can_share') === 'on' - }, - timestamp: new Date().toISOString() - } - }) - }); + + // Auto-submit permission form on checkbox change + document.querySelectorAll('.auto-save-perms-form input[type="checkbox"]').forEach(function(checkbox) { + checkbox.addEventListener('change', function() { + this.closest('form').submit(); }); }); }); \ No newline at end of file diff --git a/static/js/rooms-list.js b/static/js/rooms-list.js index 271fa5c..75068ad 100644 --- a/static/js/rooms-list.js +++ b/static/js/rooms-list.js @@ -46,137 +46,4 @@ document.addEventListener('DOMContentLoaded', function() { form.submit(); }); } - - // Log when rooms page is viewed - fetch('/api/events/log', { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - 'X-CSRFToken': document.querySelector('meta[name="csrf-token"]').getAttribute('content') - }, - body: JSON.stringify({ - event_type: 'room_list_view', - details: { - timestamp: new Date().toISOString() - } - }) - }); - - // Log when a room is opened - const openRoomButtons = document.querySelectorAll('a[href*="/room/"]'); - openRoomButtons.forEach(button => { - button.addEventListener('click', function(e) { - const roomId = this.href.split('/room/')[1]; - fetch('/api/events/log', { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - 'X-CSRFToken': document.querySelector('meta[name="csrf-token"]').getAttribute('content') - }, - body: JSON.stringify({ - event_type: 'room_open', - details: { - room_id: roomId, - timestamp: new Date().toISOString() - } - }) - }); - }); - }); - - // Log when a room is deleted - const deleteRoomForms = document.querySelectorAll('form[action*="/delete"]'); - deleteRoomForms.forEach(form => { - form.addEventListener('submit', function(e) { - const roomId = this.action.split('/rooms/')[1].split('/delete')[0]; - fetch('/api/events/log', { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - 'X-CSRFToken': document.querySelector('meta[name="csrf-token"]').getAttribute('content') - }, - body: JSON.stringify({ - event_type: 'room_delete', - details: { - room_id: roomId, - timestamp: new Date().toISOString() - } - }) - }); - }); - }); - - // Log when a room is created - const createRoomForm = document.querySelector('form[action*="/create"]'); - if (createRoomForm) { - createRoomForm.addEventListener('submit', function(e) { - const formData = new FormData(this); - fetch('/api/events/log', { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - 'X-CSRFToken': document.querySelector('meta[name="csrf-token"]').getAttribute('content') - }, - body: JSON.stringify({ - event_type: 'room_create', - details: { - room_name: formData.get('name'), - description: formData.get('description'), - timestamp: new Date().toISOString() - } - }) - }); - }); - } - - // Log when a room is edited - const editRoomForm = document.querySelector('form[action*="/edit"]'); - if (editRoomForm) { - editRoomForm.addEventListener('submit', function(e) { - const roomId = this.action.split('/rooms/')[1].split('/edit')[0]; - const formData = new FormData(this); - fetch('/api/events/log', { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - 'X-CSRFToken': document.querySelector('meta[name="csrf-token"]').getAttribute('content') - }, - body: JSON.stringify({ - event_type: 'room_update', - details: { - room_id: roomId, - room_name: formData.get('name'), - description: formData.get('description'), - timestamp: new Date().toISOString() - } - }) - }); - }); - } - - // Log when room search is performed - if (searchInput) { - let searchTimeout; - searchInput.addEventListener('input', function(e) { - clearTimeout(searchTimeout); - searchTimeout = setTimeout(() => { - if (this.value.length > 0) { - fetch('/api/events/log', { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - 'X-CSRFToken': document.querySelector('meta[name="csrf-token"]').getAttribute('content') - }, - body: JSON.stringify({ - event_type: 'room_search', - details: { - search_term: this.value, - timestamp: new Date().toISOString() - } - }) - }); - } - }, 500); - }); - } }); \ No newline at end of file diff --git a/templates/settings/settings.html b/templates/settings/settings.html index 5af4a76..d75f4b9 100644 --- a/templates/settings/settings.html +++ b/templates/settings/settings.html @@ -4,7 +4,6 @@ {% from "settings/tabs/company_info.html" import company_info_tab %} {% from "settings/tabs/security.html" import security_tab %} {% from "settings/tabs/debugging.html" import debugging_tab %} -{% from "settings/tabs/events.html" import events_tab %} {% from "settings/components/reset_colors_modal.html" import reset_colors_modal %} {% block title %}Settings - DocuPulse{% endblock %} @@ -37,11 +36,6 @@ Company Info -