Merge branch 'v20260204-03-dashboard-redirect-setting' into main

This commit is contained in:
Ivo Oskamp 2026-02-06 13:32:36 +01:00
commit 7693af9306
7 changed files with 74 additions and 1 deletions

View File

@ -1 +1 @@
v20260204-02-performance-optimizations v20260204-03-dashboard-redirect-setting

View File

@ -69,6 +69,9 @@ def create_app():
This ensures that when a user opens the site for the first time each day, This ensures that when a user opens the site for the first time each day,
they land on the dashboard regardless of the bookmarked/deeplinked URL. they land on the dashboard regardless of the bookmarked/deeplinked URL.
This behavior is controlled by the system setting `require_daily_dashboard_visit`.
When disabled (the default), users can navigate directly to any page.
""" """
# Only for normal page loads. # Only for normal page loads.
@ -99,6 +102,18 @@ def create_app():
session["daily_dashboard_seen"] = _get_today_ui_date() session["daily_dashboard_seen"] = _get_today_ui_date()
return None return None
# Check if the feature is enabled in system settings.
try:
from .models import SystemSettings
settings = SystemSettings.query.first()
if not settings or not getattr(settings, "require_daily_dashboard_visit", False):
# Feature is disabled; skip redirect.
return None
except Exception:
# On any error (e.g. column doesn't exist yet), skip redirect.
return None
today = _get_today_ui_date() today = _get_today_ui_date()
seen = (session.get("daily_dashboard_seen") or "").strip() seen = (session.get("daily_dashboard_seen") or "").strip()
if seen != today: if seen != today:

View File

@ -434,6 +434,10 @@ def settings():
if "ui_timezone" in request.form: if "ui_timezone" in request.form:
settings.ui_timezone = (request.form.get("ui_timezone") or "").strip() or "Europe/Amsterdam" settings.ui_timezone = (request.form.get("ui_timezone") or "").strip() or "Europe/Amsterdam"
# Navigation setting is in the same form (General tab), so process it here.
# Checkbox: present in form = checked, absent = unchecked.
settings.require_daily_dashboard_visit = bool(request.form.get("require_daily_dashboard_visit"))
# Autotask integration # Autotask integration
if "autotask_enabled" in request.form: if "autotask_enabled" in request.form:
settings.autotask_enabled = bool(request.form.get("autotask_enabled")) settings.autotask_enabled = bool(request.form.get("autotask_enabled"))

View File

@ -931,6 +931,7 @@ def run_migrations() -> None:
migrate_reporting_tables() migrate_reporting_tables()
migrate_reporting_report_config() migrate_reporting_report_config()
migrate_performance_indexes() migrate_performance_indexes()
migrate_system_settings_require_daily_dashboard_visit()
print("[migrations] All migrations completed.") print("[migrations] All migrations completed.")
@ -1115,6 +1116,38 @@ def migrate_jobs_archiving() -> None:
print("[migrations] migrate_jobs_archiving completed.") print("[migrations] migrate_jobs_archiving completed.")
def migrate_system_settings_require_daily_dashboard_visit() -> None:
"""Add require_daily_dashboard_visit column to system_settings if missing.
When enabled, authenticated users are redirected to the dashboard on
their first page view each day.
"""
table = "system_settings"
column = "require_daily_dashboard_visit"
try:
engine = db.get_engine()
except Exception as exc:
print(f"[migrations] Could not get engine for system_settings require_daily_dashboard_visit migration: {exc}")
return
try:
if _column_exists(table, column):
print("[migrations] system_settings.require_daily_dashboard_visit already exists.")
return
with engine.begin() as conn:
conn.execute(
text(
f'ALTER TABLE "{table}" ADD COLUMN {column} BOOLEAN NOT NULL DEFAULT FALSE'
)
)
print("[migrations] migrate_system_settings_require_daily_dashboard_visit completed.")
except Exception as exc:
print(f"[migrations] Failed to migrate system_settings.require_daily_dashboard_visit: {exc}")
def migrate_performance_indexes() -> None: def migrate_performance_indexes() -> None:
"""Add performance indexes for frequently queried foreign key columns. """Add performance indexes for frequently queried foreign key columns.

View File

@ -107,6 +107,10 @@ class SystemSettings(db.Model):
# UI display timezone (IANA name). Used for rendering times in the web interface. # UI display timezone (IANA name). Used for rendering times in the web interface.
ui_timezone = db.Column(db.String(64), nullable=False, default="Europe/Amsterdam") ui_timezone = db.Column(db.String(64), nullable=False, default="Europe/Amsterdam")
# Navigation behavior: require visiting dashboard first each day.
# When enabled, authenticated users are redirected to the dashboard on
# their first page view each day before they can navigate elsewhere.
require_daily_dashboard_visit = db.Column(db.Boolean, nullable=False, default=False)
# Autotask integration settings # Autotask integration settings
autotask_enabled = db.Column(db.Boolean, nullable=False, default=False) autotask_enabled = db.Column(db.Boolean, nullable=False, default=False)
@ -129,6 +133,7 @@ class SystemSettings(db.Model):
autotask_cached_priorities_json = db.Column(db.Text, nullable=True) autotask_cached_priorities_json = db.Column(db.Text, nullable=True)
autotask_cached_ticket_statuses_json = db.Column(db.Text, nullable=True) autotask_cached_ticket_statuses_json = db.Column(db.Text, nullable=True)
autotask_reference_last_sync_at = db.Column(db.DateTime, nullable=True) autotask_reference_last_sync_at = db.Column(db.DateTime, nullable=True)
created_at = db.Column(db.DateTime, default=datetime.utcnow, nullable=False) created_at = db.Column(db.DateTime, default=datetime.utcnow, nullable=False)
updated_at = db.Column( updated_at = db.Column(
db.DateTime, default=datetime.utcnow, onupdate=datetime.utcnow, nullable=False db.DateTime, default=datetime.utcnow, onupdate=datetime.utcnow, nullable=False

View File

@ -139,6 +139,17 @@
</div> </div>
</div> </div>
<div class="card mb-3">
<div class="card-header">Navigation</div>
<div class="card-body">
<div class="form-check form-switch">
<input class="form-check-input" type="checkbox" id="require_daily_dashboard_visit" name="require_daily_dashboard_visit" {% if settings.require_daily_dashboard_visit %}checked{% endif %} />
<label class="form-check-label" for="require_daily_dashboard_visit">Require dashboard visit on first page view each day</label>
</div>
<div class="form-text">When enabled, users are redirected to the dashboard on their first page view each day, regardless of which page they try to access.</div>
</div>
</div>
<div class="d-flex justify-content-end mt-3"> <div class="d-flex justify-content-end mt-3">
<button type="submit" class="btn btn-primary">Save settings</button> <button type="submit" class="btn btn-primary">Save settings</button>
</div> </div>

View File

@ -6,6 +6,11 @@ This file documents all changes made to this project via Claude Code.
### Added ### Added
- `docs/changelog-claude.md` - Changelog file for tracking changes made via Claude Code - `docs/changelog-claude.md` - Changelog file for tracking changes made via Claude Code
- Setting to enable/disable daily dashboard redirect requirement (Settings > General > Navigation)
- New `require_daily_dashboard_visit` column in `SystemSettings` model
- Migration in `migrations.py` to add the column
- Toggle in Settings General page under new "Navigation" card
- Default value is OFF (disabled) - users can navigate directly to any page
### Changed ### Changed
- Converted changelog to English (all project documentation must be in English) - Converted changelog to English (all project documentation must be in English)