fix dashboard table layout

This commit is contained in:
nahakubuilde
2025-06-17 19:26:25 +01:00
parent f961e426e7
commit 45799593e0
5 changed files with 38 additions and 55 deletions

12
app.py
View File

@@ -330,9 +330,8 @@ def init_app():
settings.log_level = 'WARNING'
db.session.add(settings)
# Create default admin if not exists
admin = User.query.filter_by(email='superadmin@example.com').first()
if not admin:
# Create default admin only if no users exist in the database
if User.query.first() is None:
hashed_password = bcrypt.generate_password_hash('adminsuper').decode('utf-8')
admin = User(
username='superadmin',
@@ -347,12 +346,11 @@ def init_app():
# Create initial API key for admin
api_key = ApiKey(
key=ApiKey.generate_key(),
description="Initial Admin API Key",
user_id=admin.id
description="Initial Admin API Key"
)
db.session.add(api_key)
db.session.commit()
db.session.commit()
logger.info("Created initial admin account and API key")
# Initialize the application
init_app()

View File

@@ -1,6 +1,6 @@
from flask import Blueprint, render_template, request, redirect, url_for, flash, current_app
from flask_login import login_required, current_user
from auth.models import User, Company, UserCompany
from auth.models import User, Company, UserCompany, ApiKey
from api.models import Log
from extensions import db
from datetime import datetime, timedelta
@@ -73,14 +73,21 @@ def dashboard():
end_date = datetime.now(app_tz) + timedelta(hours=1) # Include 1 hour in the future
start_date = end_date - timedelta(hours=49) # Look back 48 hours from future end time
# Get company filter if provided
# Get companies for the dropdown filter based on user role, ordered by name
if current_user.is_global_admin():
# GlobalAdmin can see all companies
companies = Company.query.order_by(Company.name).all()
else:
# Get user's companies, ordered by name
user_company_ids = [uc.company_id for uc in current_user.companies]
companies = Company.query.filter(Company.id.in_(user_company_ids)).order_by(Company.name).all()
# Get company filter if provided, otherwise use first available company
company_id = request.args.get('company_id', type=int)
# Build base query with date range filter and eagerly load relationships
from auth.models import ApiKey, Company
if not company_id and companies:
company_id = companies[0].id # Default to first company
# Convert timezone-aware dates to naive for comparison with database timestamps
# since the log timestamps are stored as naive datetime objects
start_date_naive = start_date.replace(tzinfo=None)
end_date_naive = end_date.replace(tzinfo=None)
@@ -90,38 +97,21 @@ def dashboard():
db.joinedload(Log.company)
).filter(Log.timestamp.between(start_date_naive, end_date_naive))
# Apply company-specific filtering based on user role
# Apply company-specific filtering
if current_user.is_global_admin():
# GlobalAdmin should be allowed to see all records, no matter what company/site
# GlobalAdmin with specific company selected
if company_id:
query = query.filter(Log.company_id == company_id)
# If no company_id specified, show all logs (no additional filtering)
else:
# CompanyAdmin and User should see only company log events and API Keys (sites)
# for companies they are member of
# Regular users always need company filtering
user_company_ids = [uc.company_id for uc in current_user.companies]
if not user_company_ids:
# If user has no company associations, show no logs
query = query.filter(Log.id == -1) # Impossible condition = no results
if company_id and company_id in user_company_ids:
query = query.filter(Log.company_id == company_id)
else:
if company_id and company_id in user_company_ids:
# Filter by the specific company if requested and user has access
query = query.filter(Log.company_id == company_id)
else:
# Show logs from all companies the user has access to
query = query.filter(Log.company_id.in_(user_company_ids))
query = query.filter(Log.company_id.in_(user_company_ids))
# Get the logs ordered by timestamp (newest first)
logs = query.order_by(Log.timestamp.desc()).all()
# Get companies for the dropdown filter based on user role
if current_user.is_global_admin():
# GlobalAdmin can see all companies
companies = Company.query.all()
else:
# CompanyAdmin and User should see only companies they are member of
companies = current_user.get_companies()
return render_template('frontend/dashboard.html',
title='Dashboard',

View File

@@ -13,7 +13,8 @@ pillow
Flask-Migrate
# serving the application
waitress # Production WSGI server for Windows (better than Gunicorn for Windows)
#waitress # Production WSGI server for Windows (better than Gunicorn for Windows)
redis
gunicorn # Production WSGI server (Linux/Unix only - won't work on Windows)
#psutil # System monitoring for health checks
#click # CLI tools (for database backups)

View File

@@ -181,11 +181,9 @@
<input type="text" id="daterange" name="daterange" class="form-control"
value="{{ start_date.strftime('%Y-%m-%d %H:%M') if start_date else '' }} - {{ end_date.strftime('%Y-%m-%d %H:%M') if end_date else '' }}"/>
</div>
{% if companies %}
<div class="col-md-3">
<label for="company_id" class="form-label">Company:</label>
<select class="form-select" id="company_id" name="company_id">
<option value="">All Companies</option>
<select class="form-select" id="company_id" name="company_id" required>
{% for company in companies %}
<option value="{{ company.id }}" {% if selected_company_id == company.id %}selected{% endif %}>
{{ company.name }}
@@ -193,7 +191,6 @@
{% endfor %}
</select>
</div>
{% endif %}
<div class="col-md-2">
<button type="submit" class="btn btn-primary">Apply Filter</button>
</div>
@@ -210,9 +207,7 @@
<th>Timestamp</th>
<th>Event Type</th>
<th>User Name</th>
{% if current_user.is_global_admin() and not selected_company_id %}
<th>Company</th>
{% endif %}
<th>Company</th>
<th>Site</th>
<th>Computer Name</th>
<th>Local IP</th>
@@ -227,9 +222,7 @@
</td>
<td>{{ log.event_type }}</td>
<td>{{ log.user_name }}</td>
{% if current_user.is_global_admin() and not selected_company_id %}
<td>{{ log.company.name if log.company else '' }}</td>
{% endif %}
<td>{{ log.company.name if log.company else '' }}</td>
<td>{{ log.api_key.description if log.api_key else '' }}</td>
<td>{{ log.computer_name }}</td>
<td>{{ log.local_ip or '' }}</td>
@@ -317,9 +310,14 @@
'<"row"<"col-sm-12 col-md-5"i><"col-sm-12 col-md-7"p>>',
columnDefs: [
{
targets: [5, 6, 7], // Computer Name, Local IP, and Public IP columns are now at indices 5, 6, and 7
targets: [5, 6, 7], // Computer Name, Local IP, and Public IP columns
visible: false, // Hide by default
searchable: true // Still allow searching in these columns
},
{
targets: [3], // Company column
visible: {% if current_user.is_global_admin() %}true{% else %}false{% endif %},
searchable: {% if current_user.is_global_admin() %}true{% else %}false{% endif %}
}
],
buttons: [
@@ -364,11 +362,7 @@
});
// Column names for the visibility controls
var columnNames = ['Timestamp', 'Event Type', 'User Name'];
{% if current_user.is_global_admin() and not selected_company_id %}
columnNames.push('Company');
{% endif %}
columnNames.push('Site', 'Computer Name', 'Local IP', 'Public IP');
var columnNames = ['Timestamp', 'Event Type', 'User Name', 'Company', 'Site', 'Computer Name', 'Local IP', 'Public IP'];
// Load saved column visibility from localStorage
function loadColumnVisibility() {

View File

@@ -129,7 +129,7 @@ class ConfigManager:
'logging': {
'DB_LOGGING_ENABLED': 'true',
'DB_LOGGING_FILTERED_LOGGERS': 'watchfiles.main,watchfiles.watcher,watchdog,uvicorn.access,__mp_main__,__main__,app',
'DB_LOGGING_FILTERED_LOGGERS': 'watchfiles.main,watchfiles.watcher,watchdog,uvicorn.access,__mp_main__,__main__,app,werkzeug',
'DB_LOGGING_FILTERED_PATTERNS': 'database.db,instance/,file changed,reloading',
'FILTER_FILE_WATCHER_LOGS': 'true',
'DB_LOGGING_DEDUPE_INTERVAL': '1',