mirror of
https://github.com/DRYTRIX/TimeTracker.git
synced 2026-05-19 12:50:11 -05:00
3b6bcc890b
Add has_enabled_modules(category) helper and wrap Finance & Expenses folder so it only renders when at least one FINANCE module is enabled. Fixes empty folder visible after disabling all modules in a category. Closes #481 Co-authored-by: Cursor <cursoragent@cursor.com>
146 lines
4.6 KiB
Python
146 lines
4.6 KiB
Python
"""
|
|
Module Helper Utilities
|
|
|
|
Provides decorators and helper functions for checking module availability
|
|
and protecting routes based on module flags.
|
|
"""
|
|
from functools import wraps
|
|
from flask import abort, redirect, url_for, flash, current_app
|
|
from flask_login import current_user
|
|
from flask_babel import gettext as _
|
|
from app.models import Settings
|
|
from app.utils.module_registry import ModuleRegistry
|
|
|
|
|
|
def module_enabled(module_id: str, redirect_to: str = None):
|
|
"""
|
|
Decorator to require a module to be enabled for a route.
|
|
|
|
Args:
|
|
module_id: The module ID to check
|
|
redirect_to: Optional route name to redirect to if module is disabled
|
|
|
|
Usage:
|
|
@module_enabled("calendar")
|
|
def view_calendar():
|
|
return render_template("calendar/view.html")
|
|
"""
|
|
def decorator(f):
|
|
@wraps(f)
|
|
def decorated_function(*args, **kwargs):
|
|
if not current_user.is_authenticated:
|
|
if redirect_to:
|
|
return redirect(url_for(redirect_to))
|
|
abort(403)
|
|
|
|
settings = Settings.get_settings()
|
|
if not ModuleRegistry.is_enabled(module_id, settings, current_user):
|
|
if current_user.is_admin:
|
|
module = ModuleRegistry.get(module_id)
|
|
module_name = module.name if module else module_id
|
|
flash(
|
|
_("Module '%(module)s' is disabled. Enable it in Settings.", module=module_name),
|
|
"warning"
|
|
)
|
|
if redirect_to:
|
|
return redirect(url_for(redirect_to))
|
|
return redirect(url_for('admin.settings'))
|
|
abort(403)
|
|
|
|
return f(*args, **kwargs)
|
|
return decorated_function
|
|
return decorator
|
|
|
|
|
|
def is_module_enabled(module_id: str) -> bool:
|
|
"""
|
|
Check if a module is enabled for the current user.
|
|
|
|
Args:
|
|
module_id: The module ID to check
|
|
|
|
Returns:
|
|
True if module is enabled, False otherwise
|
|
"""
|
|
if not current_user.is_authenticated:
|
|
return False
|
|
|
|
try:
|
|
settings = Settings.get_settings()
|
|
return ModuleRegistry.is_enabled(module_id, settings, current_user)
|
|
except Exception:
|
|
# If we can't check, default to False for safety
|
|
return False
|
|
|
|
|
|
def get_enabled_modules(category=None):
|
|
"""
|
|
Get all enabled modules, optionally filtered by category.
|
|
|
|
Args:
|
|
category: Optional ModuleCategory to filter by
|
|
|
|
Returns:
|
|
List of enabled ModuleDefinition objects
|
|
"""
|
|
if not current_user.is_authenticated:
|
|
return []
|
|
|
|
try:
|
|
settings = Settings.get_settings()
|
|
modules = ModuleRegistry.get_enabled_modules(settings, current_user)
|
|
|
|
if category:
|
|
from app.utils.module_registry import ModuleCategory
|
|
if isinstance(category, str):
|
|
try:
|
|
category = ModuleCategory(category)
|
|
except ValueError:
|
|
return []
|
|
modules = [m for m in modules if m.category == category]
|
|
|
|
return modules
|
|
except Exception:
|
|
return []
|
|
|
|
|
|
def has_enabled_modules(category=None) -> bool:
|
|
"""
|
|
Check whether a category has any enabled modules for the current user.
|
|
|
|
Args:
|
|
category: Optional ModuleCategory (or its value as string). If omitted/invalid, returns False.
|
|
|
|
Returns:
|
|
True if at least one module in the category is enabled for the current user.
|
|
"""
|
|
return bool(get_enabled_modules(category))
|
|
|
|
|
|
def init_module_helpers(app):
|
|
"""
|
|
Initialize module helper functions for use in templates and routes.
|
|
|
|
This should be called during app initialization.
|
|
"""
|
|
# Initialize module registry
|
|
ModuleRegistry.initialize_defaults()
|
|
|
|
@app.context_processor
|
|
def inject_module_helpers():
|
|
"""Make module helpers available in templates"""
|
|
from app.utils.module_registry import ModuleCategory
|
|
return {
|
|
"is_module_enabled": is_module_enabled,
|
|
"get_enabled_modules": get_enabled_modules,
|
|
"has_enabled_modules": has_enabled_modules,
|
|
"get_modules_by_category": lambda cat: ModuleRegistry.get_by_category(cat),
|
|
"ModuleCategory": ModuleCategory,
|
|
}
|
|
|
|
# Also make it available as a global function
|
|
app.jinja_env.globals['is_module_enabled'] = is_module_enabled
|
|
app.jinja_env.globals['get_enabled_modules'] = get_enabled_modules
|
|
app.jinja_env.globals['has_enabled_modules'] = has_enabled_modules
|
|
|