Merge branch 'v20260204-03-dashboard-redirect-setting' into main
This commit is contained in:
commit
7693af9306
@ -1 +1 @@
|
|||||||
v20260204-02-performance-optimizations
|
v20260204-03-dashboard-redirect-setting
|
||||||
|
|||||||
@ -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:
|
||||||
|
|||||||
@ -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"))
|
||||||
|
|||||||
@ -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.
|
||||||
|
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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>
|
||||||
|
|||||||
@ -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)
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user