- Inline <script> in <head> applies edp_theme from localStorage before first
paint — no flash of unstyled content
- Bootstrap 5.3 data-bs-theme + custom data-edp-theme attribute for overrides
- Dark palette mirrors portal (bg #0d1117, surface #161b22, card #1c2128,
accent-blue #388bfd, text #e6edf3, borders #30363d)
- CSS tokens for both themes via :root and [data-edp-theme='dark']
- All Bootstrap components overridden in dark mode: cards, tables, forms,
modals, alerts, breadcrumbs, code, badges, inputs
- Moon/sun toggle button in topbar; sun shown in dark mode, moon in light
- Shared localStorage key 'edp_theme' — setting persists across all EDP apps
The compliance history section had two bugs:
- {% if compliance_log %} opened a card div and card-header div that were
never closed, then accidentally wrapped {% if check_history %} inside it
- {% if asset.asset_type in Laptop/Desktop %} was missing its closing {% endif %}
Fix: remove the broken compliance_log wrapper; check_history now sits at the
correct nesting level with its own properly closed card structure; added the
missing {% endif %} for the asset_type block.
- Green info banner explains that hardware fields persist between saves
- Identifiers section badge shows 'These fields clear after each save'
- MAC Address gets same warning hint
- Submit button relabelled 'Save & Add Next' in add mode
- 'Reset All' button clears localStorage and the entire form
- localStorage saves all shared fields on submit; restores on page load
(only Service Tag, Asset Tag and MAC Address are cleared each time)
- Cursor auto-focuses Service Tag field for fast keyboard entry
- Dell pre-fill still takes priority over stored state
New database table: maintenance_records
- Fields: asset, start_date, end_date, status (open/in_progress/closed),
initial_diagnosis, action_taken, action_result
New routes (/maintenance/):
- List with status + asset filters and pagination
- POST /new — create record (editor+); auto-sets asset status to 'maintenance'
- GET /<id>/edit — opens list page with modal pre-filled
- POST /<id>/update — save edits; auto-clears 'maintenance' status on close
- POST /<id>/delete — remove record
UI:
- Bootstrap modal form shared for add and edit
- Clicking any table row opens the modal pre-filled with that row's data
- Asset field locked in edit mode (cannot change asset)
- Delete button per row (with confirmation)
- Sidebar: 'Maintenance' link added under Hardware section
Users are sourced exclusively from the portal (via SSO auto-create or
the Sync from Portal button). The Add User form and create_admin route
are removed to prevent out-of-sync local-only accounts.
A footer hint now links admins to the portal settings page.
- Portal: add /api/internal/itassets-users endpoint (returns all portal users
with itassets access + their effective role)
- IT Assets: add PORTAL_INTERNAL_URL config key
- IT Assets: add POST /settings/sync-from-portal route (admin only) — pulls
users from the portal API and upserts them locally
- Settings page: 'Sync from Portal' button next to the users table header
- start-dev.sh: pass INTERNAL_SYNC_SECRET and ITASSETS_INTERNAL_URL to portal;
pass PORTAL_INTERNAL_URL and INTERNAL_SYNC_SECRET to itassets
- Also includes 'Back to Portal' icon button added to sidebar footer
Auth:
- Fix local login (was redirecting to portal; now authenticates AdminUser directly)
- Portal SSO still takes priority in production via nginx headers
Role system (admin | editor | readonly):
- New app/utils/decorators.py with editor_required and admin_required decorators
- All write routes protected with editor_required (create/edit/delete/import/mask)
- Settings user management protected with admin_required
- Sidebar hides write-only links for readonly users
- Dashboard quick actions and list page buttons hidden for readonly
Settings page:
- Role colour badges (admin=red, editor=blue, readonly=grey)
- Inline role changer per user (dropdown auto-submit)
- Reset password modal per user
- Delete user button with confirmation
- Add user form includes role selector with legend
Portal user sync:
- New /internal/sync-user endpoint receives user pre-creation from portal
- INTERNAL_SYNC_SECRET added to config
- portal/config.py: added internal_url for itassets app so _sync_user_to_app works