Commit graph

19 commits

Author SHA1 Message Date
785f077c50 feat: change default theme from system to light mode 2026-06-23 10:28:31 -05:00
1ce1738fc5 fix: set explicit robots meta, Twitter Card tags, and WebP favicon
Adds <meta name='robots'>, twitter:card/title/description meta tags, and WebP favicon reference to the root layout. Fixes title duplication (TowerOps | TowerOps -> Home | TowerOps) by passing page_title from the page controller.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-05-31 09:53:37 -05:00
39e588c686 fix: API token access control, admin form crash, MIB validation, CSP dedup
- Add organization membership check before API token creation
- Fix admin security allowlist form reading current_user instead of current_scope.user
- Use recursive File.ls instead of Path.wildcard to include hidden files in MIB validation
- Add upload size check before ZIP extraction in MIB controller
- Centralize CSP in SecurityHeaders plug with per-request nonces instead of 'unsafe-inline'
2026-05-12 09:08:57 -05:00
e97748437c build(assets): split coverage hooks into a lazy-loaded chunk
Switch esbuild to ESM with --splitting and load app.js as type=module.
Heavy hooks now ship in their own chunk and only download when their
LiveView mounts.

- assets/js/lib/leaflet.ts: extract ensureLeaflet (vendored Leaflet
  loader) into a shared module with a typed window.L declaration.
- assets/js/hooks/coverage_hooks.ts: extract CoverageMap,
  MultiCoverageMap, and CoverageLocationPicker (~510 lines) with
  proper interface types for hook context and tightened typing on
  payloads / event handlers (CoveragePayload is now a real type).
- app.ts: replace those three inline hook bodies with lazyHook
  stubs that call import('./hooks/coverage_hooks') on first mount,
  forwarding lifecycle hooks once the chunk resolves. Also adds a
  scoped `declare const L: any` so the remaining Leaflet hooks
  type-check.
- root.html.heex: switch the script tag to type=module so the
  emitted ESM bundle can use dynamic import().
- esbuild config: add --splitting --format=esm.

Build output now produces:
  app.js                      1.2 MB
  coverage_hooks-<hash>.js   16  KB  (lazy)
  chunk-<hash>.js             2.4 KB  (shared, lazy)
2026-05-06 16:11:32 -05:00
df1d361249 feat: add Plausible analytics to all pages 2026-04-29 13:46:24 -05:00
8e25034e69 Move sidebar-collapsed class to <html> element
LiveView DOM patching was stripping the client-side sidebar-collapsed
class from #sidebar-wrapper on every navigation. Fix: put the class
on document.documentElement which LiveView never touches.

- Sync script in <head> applies state before first paint (no flash)
- Hook click handler toggles on <html> + saves to localStorage
- CSS selectors updated to html.sidebar-collapsed
- Removed phx-click JS.toggle_class (hook handles toggle directly)
2026-03-13 14:28:38 -05:00
9bef1b289d
feat: add status emoji to page titles
Add colored circle emoji (🔴/🟡/🟢) to page titles based on organization
health status:
- 🔴 Red: Critical alerts (device_down, agent_offline, severity 1)
- 🟡 Yellow: Warning alerts (severity 2 or any active alerts)
- 🟢 Green: No active alerts

Provides at-a-glance status visibility in browser tabs.

Note: Favicon remains static stoplight, only page title is dynamic.
2026-03-06 14:45:02 -06:00
c110832b42
Revert "feat: add status emoji to page titles"
This reverts commit f3873e0da7.
2026-03-06 14:43:13 -06:00
f3873e0da7
feat: add status emoji to page titles
Add colored circle emoji (🔴/🟡/🟢) to page titles based on organization
health status:
- 🔴 Red: Critical alerts (device_down, agent_offline, severity 1)
- 🟡 Yellow: Warning alerts (severity 2 or any active alerts)
- 🟢 Green: No active alerts

Provides at-a-glance status visibility in browser tabs.
2026-03-06 14:42:55 -06:00
d3d5d1e706
feat: add TowerOps suffix to all page titles
Add '| TowerOps' suffix to page titles so users can easily identify
TowerOps tabs when multiple browser tabs are open.

Examples:
- Dashboard → 'Dashboard | TowerOps'
- Equipment Details → 'Router-1 | TowerOps'
- No page_title → 'TowerOps'

Uses Phoenix LiveView's suffix parameter on live_title component.
2026-03-05 13:51:28 -06:00
ade7e2fe15
fix: correct mail adapter message interpolation in login page
Fixes fragmented translation that displayed raw '%{link}' placeholder text
instead of properly interpolated link in development mail adapter notice.

Changes:
- Consolidate separate translation calls into single interpolated string
- Use raw() helper to safely inject HTML link into translated text
- Update Spanish translation to include %{link} placeholder
- Extract updated translations with mix gettext.extract

Before: "To see sent emails, visit %{link}. the mailbox page."
After: "To see sent emails, visit the mailbox page." (with proper link)
2026-03-05 13:32:34 -06:00
243b773e39 i18n: wrap all user-facing strings in gettext() 2026-02-14 17:44:01 -06:00
9e7ee5099d refactor: fix all credo strict issues, format all code, fix broken routes
- Fix broken route paths in dashboard (/discovery, /subscribers/trace, /config-changes)
- Fix insights empty state settings link (org-scoped route)
- Add underscores to all 86400 literals across 6 files
- Alphabetize aliases in search.ex and agent_channel.ex
- Extract changelog parser helper to reduce nesting
- Extract dashboard impact calculation to reduce nesting
- Refactor agent_channel config change detection (pattern match, extract function)
- Combine double Enum.reject into single call in trace.ex
- Fix line length in trace.ex search query
- Replace length/1 > 0 with != [] in trace_live
- Run mix format on all files
2026-02-13 19:34:40 -06:00
bc128388ba feat: add loading skeletons and page transitions 2026-02-13 19:18:28 -06:00
06fde717c0
accessibility and poller updates 2026-01-26 13:02:03 -06:00
fbad8c64b2
dark mode 2026-01-20 16:56:49 -06:00
dffa46dfde
Improve UI styling and remove DaisyUI dependencies
- Remove default Phoenix branding and create custom layouts
- Replace DaisyUI classes with custom Tailwind components throughout
- Add authenticated layout with navigation bar for organization pages
- Redesign all core components (buttons, forms, tables, alerts)
- Make dashboard stat cards clickable to navigate to respective pages
- Update alert acknowledge button to only show for equipment down alerts
- Add consistent dark mode support across all pages
- Implement modern design with zinc color palette and improved spacing
2026-01-03 11:02:38 -06:00
c52f313e2d
1. User Authentication
- Full auth system with email/password (using phx.gen.auth)
  - Login, registration, password reset
  - Session management with remember-me functionality
  - Magic link login support

  2. Organization Management
  - Multi-tenant organization system
  - Organizations schema with unique slugs
  - Automatic organization creation when users register
  - Organization switcher UI at /orgs

  3. Membership System
  - Users can belong to multiple organizations
  - 4 permission levels: Owner, Admin, Member, Viewer
  - Complete permission matrix implemented
  - Join/leave organizations

  4. Invitation System
  - Email-based invitations with secure tokens
  - 7-day expiration on invites
  - Track who invited and who accepted

  5. Authorization
  - Full policy system (Organizations.Policy)
  - can?(membership, :action, :resource) helper
  - Enforced via plugs in router

  6. LiveView Pages
  - /orgs - List all your organizations
  - /orgs/new - Create new organization
  - /orgs/:slug - Organization dashboard (placeholder)

  7. Database Schema
  - users table
  - organizations table
  - organization_memberships table
  - organization_invitations table
  - All migrations run successfully
2025-12-21 13:31:59 -06:00
ba463dc5a2
init 2025-12-21 11:10:43 -06:00