Skip to content

Settings Page Architecture

Overview

The /settings page is a unified, role-gated settings UI with a left sidebar navigation pattern. Regular users see personal settings (My Account, Connectors), while admin users (is_staff=True) also see workspace configuration sections (General & Branding, Chat Modules & FAQs, User Management, Knowledge Folders).

Layout

/settings
├── Left sidebar (260px)         → role-gated nav items
├── Right content area (flex-1)  → HTMX loads section partials
├── USER SECTIONS (@login_required):
│   ├── My Account               → profile, department
│   └── Connectors               → external service connections
└── ADMIN SECTIONS (@staff_member_required):
    ├── General & Branding       → university name, logo, welcome message
    ├── Chat Modules & FAQs      → module activation, prompts, FAQ management
    ├── User Management          → user table, role editing, search/filter
    └── Knowledge Folders        → admin overview of all folders + stats

On mobile, the sidebar collapses to a horizontal scrollable pill nav.

Key Files

File Purpose
templates/pages/settings.html Shell page with sidebar nav + #settings-content target
apps/main_app/apis/settings_apis.py All section HTMX endpoints (GET renders partial, POST saves)
apps/main_app/services/app_config_service.py Cached singleton access to AppConfig
apps/main_app/models.py AppConfig model (branding fields only)
templates/partials/settings/*.html Section partial templates
apps/main_app/tests/test_settings.py Access control and save endpoint tests

Data Model: AppConfig

Singleton model holding institution branding. Only one AppConfig can be active at a time — the save() method deactivates all others when is_active=True.

Field Type Purpose
university_name CharField Displayed in header and communications
university_logo_url URLField Logo image URL
welcome_message TextField Chat home page greeting
support_email EmailField Contact email for users
is_active BooleanField Singleton control flag

Access via AppConfigService.get_config() which provides module-level caching. Call AppConfigService.refresh_cache() after any writes.

HTMX Interaction Pattern

  1. User clicks a sidebar nav item
  2. hx-get="/api/htmx/settings/<section>/" fires, loading the partial into #settings-content
  3. JavaScript updates the active nav highlight and URL hash
  4. Forms within partials use hx-post to save and swap the content area with a success message

URL hash deep-linking is supported — loading /settings#users will auto-select that section.

Endpoints

User Endpoints (@login_required)

Method URL View Template
GET /api/htmx/settings/account/ settings_account settings/account.html
POST /api/htmx/settings/account/save/ save_account_settings settings/account.html
GET /api/htmx/settings/connectors/ settings_connectors settings/connectors.html

Admin Endpoints (@staff_member_required)

Method URL View Template
GET /api/htmx/settings/general/ settings_general settings/general.html
POST /api/htmx/settings/general/save/ save_general_settings settings/general.html
GET /api/htmx/settings/modules/ settings_modules settings/modules.html
POST /api/htmx/settings/modules/<id>/activate/ activate_module settings/modules.html
POST /api/htmx/settings/modules/<id>/edit/ save_module settings/modules.html
POST /api/htmx/settings/faqs/create/ create_faq settings/modules.html
POST /api/htmx/settings/faqs/<id>/delete/ delete_faq settings/modules.html
GET /api/htmx/settings/users/ settings_users settings/users.html
POST /api/htmx/settings/users/<id>/role/ update_user_role (inline swap)
GET /api/htmx/settings/knowledge-admin/ settings_knowledge_admin settings/knowledge_admin.html

Access Control

  • User-facing endpoints use @login_required — redirects to login if unauthenticated
  • Admin endpoints use @staff_member_required (from django.contrib.admin.views.decorators) — redirects non-staff users
  • The sidebar template uses {% if user.is_staff %} to hide admin nav items from regular users
  • Tests in test_settings.py verify that regular users get 302 redirects on admin endpoints

Seed Data

Run python manage.py init_app_config to create the default AppConfig with Virginia State University branding. This is idempotent — it skips creation if an active config already exists.