Commit graph

106 commits

Author SHA1 Message Date
253657280b Revert "refactor: apply custom color palette across entire codebase"
This reverts commit 5a7cdc7138.
2026-06-23 12:26:57 -05:00
5a7cdc7138 refactor: apply custom color palette across entire codebase
- Replace gray->cool-steel, blue/indigo->cerulean, red->sweet-salmon, yellow/amber->wheat
- Dark sidebar: sidebar/footer use cool-steel-800 bg, text lightened for contrast
- ~11,600 color replacements across ~99 files
- Update tests for new color class names
2026-06-23 10:58:48 -05:00
b76637c14f refactor: remove icons from sidebar and mobile nav menu items 2026-06-23 10:18:40 -05:00
3a408a8dc1 Security hardening + performance fixes across codebase
CRITICAL:
- Membership: remove :role/:org_id/:user_id from mass-assignment cast; use explicit create_changeset/4 and role_update_changeset/2
- GraphQL member resolver: add authorize_invite/3 checking admin/owner role and role hierarchy
- REST invitations controller: add auth check for invite creation

HIGH:
- ApiToken: remove :organization_id/:user_id from cast; use explicit create_changeset/4

MEDIUM:
- Move 8 LiveView Ecto queries into context modules (Admin, Alerts, Coverages, OnCall, Snmp)
- Replace Process.put/Process.get with socket assigns for unresolved_alert_count (user_auth + layouts + 50 templates)
- Add batch get_utilization_for_interfaces/1 to eliminate N+1 capacity queries in device show
- Replace Process.sleep with Process.monitor/assert_receive or Process.send_after in 5 test files

LOW:
- Add handle_params/3 to UserResetPasswordLive, UserRegistrationLive, StatusPageLive
- Remove redundant Repo.preload calls; add preloads to list_site_devices/1
- Fix @impl annotations and credo nesting warnings
2026-06-21 17:40:50 -05:00
d0160f7d8a credo fixes 2026-06-14 08:27:57 -05:00
4421727e61 fix: resolve all Elixir 1.20 type system warnings across project
Removes unreachable catch-all clauses, drops unused `require Logger`
lines, adds pin operators to bitstring size patterns, reorders function
heads for correct dispatch, and replaces deprecated LoggerBackends calls.
2026-05-28 14:52:30 -05:00
8338d0af1e fix: remaining bugs.md findings — Repo calls, process dict, CSS, rate limits, Oban, debug route
- Extract Repo calls from LiveViews into Agents.get_agent_token_for_org/2
  and Accounts.verify_new_totp_device/2 context functions
- Remove Process dictionary usage for cookie consent; use explicit assigns
- Reject url() references in status page custom CSS changeset
- Add per-organization rate limit check alongside per-IP
- Document Oban flush as emergency-only with audit logging
- Gate /admin/headers behind dev_routes (debug endpoint)
2026-05-11 19:34:18 -05:00
5a9381f91a feat: add /coverage RF prediction feature scaffold
End-to-end CRUD scaffold for per-site, per-antenna RF coverage
prediction. Schema, context, antenna registry, Oban worker stub, and
three LiveViews are wired up; the actual ITM + LIDAR + buildings
compute pipeline lands in a follow-up.

- Migration + Coverage schema with full validation (RF params, pixel-
  budget cap, antenna_slug existence). organization_id excluded from
  cast (programmatic-only).
- Coverages context: org-scoped CRUD, validate_site_in_organization
  rejects cross-tenant site_id refs at insert/update, queue_compute
  with PubSub broadcast on per-coverage and per-org topics.
- MSI Planet .ant parser + persistent_term registry loaded at boot
  from priv/antennas/. Two synthetic .ant fixtures (omni + 90deg
  sector) bundled.
- CoverageWorker on new :coverage Oban queue (concurrency 2). Job
  args carry organization_id; worker refuses to run on org mismatch.
  Stub flips status to "failed" with "compute not yet implemented"
  so the UI flow is exercisable.
- LiveViews: index (org-wide, live status updates), form (antenna
  picker grouped by manufacturer), show (status banners, params
  panel, map placeholder). Sidebar nav link added.
- Routes /coverage, /coverage/new, /coverage/:id, /coverage/:id/edit
  under :require_authenticated_user_with_default_org.
- 41 new tests covering schema validation, .ant parsing, context
  CRUD with cross-org guards, Oban job enqueue.
2026-05-06 13:44:14 -05:00
23be5c2ec2 fix: friendlier websocket reconnect message 2026-05-05 09:07:33 -05:00
06ca0390f0 ui: hide weathermap navigation links (#174)
Commented out weathermap navigation in sidebar and mobile menu.
Feature not ready for production use yet.

Files: lib/towerops_web/components/layouts.ex
Changelog: CHANGELOG.txt

Reviewed-on: graham/towerops-web#174
2026-03-25 16:40:11 -05:00
a97340873f feat: Add network weathermap with real-time utilization visualization (#172)
- Create WeathermapLive module at /weathermap with 60s auto-refresh
- Extend Topology.get_topology_for_weathermap with bandwidth utilization data
- Add WeathermapViewer JavaScript hook with color-coded edges:
  * Green (0-30%) → Yellow (30-60%) → Orange (60-80%) → Red (80%+)
- Display throughput/capacity labels on edges (e.g., '847 Mbps / 1 Gbps')
- Add utilization stats dashboard with link count by usage level
- Support full-screen mode for NOC displays
- Integrate with existing dark mode and responsive design
- Add navigation links in sidebar and mobile menu

Technical implementation:
- Leverages existing Capacity module for interface utilization calculations
- Extends topology edges with utilization_level, utilization_pct, throughput_bps
- Builds on NetworkMapLive foundation with enhanced edge styling
- Auto-refresh via Phoenix PubSub and 60s timer
- Filter support for high/critical utilization links

Reviewed-on: graham/towerops-web#172
2026-03-25 16:26:11 -05:00
d0e2ead923 hide rf links from sidebar navigation (#51)
Reviewed-on: graham/towerops-web#51
2026-03-16 17:54:57 -05:00
316725acfd fix: reduce left margin on integrations page (#34)
Reduced left padding from lg:px-8 (32px) to lg:pl-4 (16px) to bring
page content closer to the sidebar navigation.

Reviewed-on: graham/towerops-web#34
2026-03-15 18:29:03 -05:00
7c8731f86a fix: make sidebar sticky with header and resolve all credo issues (#32)
- Changed sidebar from fixed to sticky positioning
- Wrapped sidebar and main content in flex container
- Sidebar now sticks to top along with header when scrolling
- Removed unused Ecto.Query import from gps_sync.ex

Credo improvements (17 → 0 remaining):
- Replaced all length/1 checks with empty list comparisons
- Extracted helper functions to reduce nesting depth
- Split complex functions into smaller, testable units
- Applied 'with' statements for clearer control flow
- Refactored high-complexity functions (cyclomatic complexity)
- Files improved: storm_detector, alert_notification_worker,
  alert_digest_worker, gps_sync, statistics_sync, device_sync,
  site_sync, site_correlation, reports_live, topology,
  pagerduty/client, cn_maestro/sync

Reviewed-on: graham/towerops-web#32
2026-03-15 18:19:09 -05:00
42bfc8b9d2 paperclip/TOW-21-uisp-integration-phase1 (#31)
Reviewed-on: graham/towerops-web#31
2026-03-15 17:57:36 -05:00
7251930404
add mobile app websocket channel and improve QR linking UX
- add MobileSocket for token-authenticated mobile WebSocket connections
- add MobileChannel with org-level and device-level real-time events
- add /mobile/socket endpoint for iOS app connections
- add "Link Mobile App" to user dropdown menu for discoverability
- improve QR code page with numbered steps and clearer instructions
- add socket/channel tests (17 total)
2026-03-13 17:28:36 -05:00
cc6dfab889
Move theme toggle from header to user settings
Remove the theme toggle dropdown from the nav bar and its component
definition. Theme selection already exists in Account Settings → Personal.
2026-03-13 16:51:33 -05:00
529a6138d1
fix: align sidebar bottom border with footer border
Adjust sidebar bottom section padding from py-3 to py-3.5 to align
the horizontal border with the footer border. Also remove unused
private functions from settings_live and fix credo warnings.
2026-03-13 16:29:44 -05:00
9bae7a886a Add page descriptions + rename Schedules to On-Call
- Alerts: add description subtitle
- On-Call (was Schedules): renamed in sidebar + page title, add description
- Maintenance: add description subtitle
- Trace: add title + description (was missing both)
- Sidebar nav updated: Schedules → On-Call
- All pages now have contextual help text explaining their purpose
2026-03-13 15:30:39 -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
7149ab71cd Fix sidebar toggle persisting across navigations
- Add updated() callback to SidebarCollapse hook so state is re-applied
  after LiveView DOM patches (which strip client-side classes)
- Add inline script for synchronous state restore (no flash on nav)
- Sidebar now stays expanded/collapsed until manually toggled
2026-03-13 14:02:19 -05:00
509e4f7eb3 Fix footer positioning + add layout tests
- Main wrapper uses flex column with min-h to push footer to bottom
- Add 12 tests covering sidebar nav, top bar, mobile menu, user menu,
  org switcher, collapse toggle, active page highlighting, beta banner,
  conditional sites link, and footer rendering
2026-03-13 13:57:55 -05:00
5a8e3885a9 Refactor nav: horizontal top bar → sidebar layout
- Replace cramped horizontal nav with grouped sidebar navigation
- Sections: Monitor, Respond, Analyze with logical grouping
- Collapsible sidebar with localStorage persistence
- Tooltips on hover when collapsed (icon-only mode)
- Slim top bar: search, alerts bell, help, theme toggle, user menu
- Org switcher + settings pinned to sidebar bottom
- Mobile: grouped slide-out panel matches sidebar sections
- Smooth CSS transitions on collapse/expand
2026-03-13 13:38:20 -05:00
0791089c18
ux: show search button in header on mobile/collapsed menu state
Change search trigger from hidden-on-mobile to always visible, hiding
only the text label and keyboard shortcut hint on small screens.
2026-03-12 15:42:01 -05:00
7f11a890a8
feat: move theme selector to user settings, remove from nav
Add an Appearance section to the Personal tab in user settings with
three clearly labelled options (Auto/Light/Dark). A ThemeSelector hook
reads localStorage to highlight the active choice and updates it when
selection changes. Remove the dropdown toggle from both the main nav
and admin nav.
2026-03-12 15:11:35 -05:00
5d1d277697
feat: add alert count badge to notification bell
Shows a red badge on the bell icon with the unresolved alert count.
Displays the number when <= 100, blank red dot when > 100 (Apple-style).
Count is loaded at mount and updated live when alerts change via PubSub.
Uses process dictionary pattern (same as cookie consent) so no template
changes needed across the 41 LiveView layouts.
2026-03-12 14:06:18 -05:00
1b8fb606a5
remove dedicated capacity page from nav and routing
Capacity functionality will be surfaced through insights instead.
2026-03-12 12:20:23 -05:00
5026614bf3
fix: nav overflow on small screens and fix bad gettext translations
Bump desktop nav breakpoint from md (768px) to lg (1024px) so the
mobile hamburger menu is used on medium-width screens instead of
nav items overflowing outside the viewport.

Clear all 65 bad fuzzy translations in English .po files (e.g.
"Navigation" was incorrectly translated to "Pagination") and fix
49 fuzzy entries in Spanish .po files with correct translations.
2026-03-11 14:00:31 -05:00
0cd2ed3567
feat: add on-call schedules and escalation policies
Built-in PagerDuty-equivalent system for on-call scheduling and alert
escalation. Users can now manage schedules, rotation layers, overrides,
and escalation policies directly in the app alongside PagerDuty.

- On-call schedules with rotation layers (daily/weekly/custom), member
  management, and temporary overrides
- Escalation policies with ordered rules, timeout-based escalation,
  and user/schedule targets
- Automatic escalation via Oban worker with configurable repeat count
- Email notifications via Swoosh for on-call alerts
- Resolver computes who's on-call from layer stacking and overrides
- AlertNotificationWorker integration: starts escalation alongside
  PagerDuty, acknowledges/resolves incidents on alert state changes
- Device and organization schemas support escalation_policy_id
- Escalation policy picker on device form
- Schedules nav item with tabbed index (schedules + escalation policies)
- Full CRUD UI for schedules, layers, members, overrides, rules, targets
- 62 LiveView tests, 56 context/schema/resolver/escalation tests
- 26 E2E Playwright tests for smoke and critical path coverage
2026-03-11 12:32:54 -05:00
1c222f8ff5
feat: add capacity insight worker, UI, and reporting views
Add CapacityInsightWorker (every 15 min) that generates critical/warning
insights when backhaul utilization exceeds 90%/75% and auto-resolves
when it drops below 70%.

Add capacity and utilization columns to the device ports tab with
set/clear capacity controls. Add organization-level /capacity page
with summary cards and per-site capacity table. Add capacity summary
card to site show page. Add Capacity link to nav menu.
2026-03-07 14:42:40 -06:00
c86ca57864
feat: add real-time status emoji updates in page titles
Dynamically update page title emoji when device/alert status changes:
- Add PubSub broadcasts when alerts are created/resolved
- Create StatusTitleComponent LiveComponent to subscribe to alert changes
- Add StatusTitle JavaScript hook to update document.title in real-time
- Subscribe to organization:alerts channel on LiveView mount
- Push emoji update events when alert status changes

This provides immediate visual feedback in browser tabs when
critical/warning/healthy status changes without requiring page refresh.
2026-03-06 14:49:44 -06: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
4b4bb2668f
feat: add billing tab to organization settings
Implements Phase 6 of Stripe billing integration:
- Add Billing tab to organization settings page
- Display subscription status, device usage, and estimated costs
- "Upgrade to Paid Plan" button for free tier orgs
- "Manage Billing" button to access Stripe Customer Portal
- Billing information panel showing subscription details
- Support for dark mode and responsive design

Also fixes organization name truncation in top navigation:
- Long organization names now show with ellipsis instead of being cut off
- Added max-w-xs constraint and truncate class to org switcher button
2026-03-06 11:08:05 -06:00
edeeacfefb
Add Exceptions link to admin nav bar 2026-02-17 10:44:03 -06:00
0f9fac76d9 Add maintenance windows LiveView UI
- Index page with All/Active/Upcoming/Past filter tabs
- Show page with active banner, edit/delete actions
- Form page with scope picker (org-wide/site/device), datetime fields
- Nav link added to desktop and mobile nav
2026-02-16 10:26:10 -06:00
2735c1a032 Add onboarding flow for new organizations 2026-02-16 10:14:45 -06:00
47b364a112
Fix Gaiia inventory matching, mapping UX, and logo link
- Fetch MAC address from Gaiia custom fields during inventory sync
- Remove name-based device matching (model names caused false matches)
- Keep IP-only matching for device suggestions
- Make unmapped rows clickable in the Gaiia mapping table
- Point authenticated logo link to /dashboard instead of /orgs
- Fix flaky monitor test teardown race condition
2026-02-15 17:41:43 -06:00
c790794191 Fix tests, credo issues, and Gaiia sync bugs
- Fix CLOAK_KEY placeholder in nix shell (invalid base64)
- Fix error HTML test assertion to match actual template
- Fix Gaiia sync: read 'subnet' field instead of 'block' for IP blocks
- Fix Gaiia sync: extract nested status name from subscription objects
- Fix security headers tests for environment detection
- Fix mobile auth tests to use raw_token
- Fix LiveView test assertions to match actual template content
- Fix SNMP config test expectations for test environment
- Refactor: resolve all Credo complexity/nesting issues
  - Extract helper functions in NetBox sync, VISP sync, Sonar sync
  - Flatten nested conditionals in settings, integrations, alerts
  - Use with/validate_present pattern for connection testing
2026-02-15 11:55:49 -06:00
172b830b6b ui: add org settings and user settings to mobile nav 2026-02-15 09:22:48 -06:00
02474c529f ui: major redesign - NOC dashboard, consolidated nav, dense tables, flat alerts 2026-02-14 20:15:07 -06:00
243b773e39 i18n: wrap all user-facing strings in gettext() 2026-02-14 17:44:01 -06:00
0f7e91af0c ui: remove Agents from top-level nav, accessible via org settings tab 2026-02-14 14:03:49 -06:00
ad6e9b91a3 feat: add global CSS polish — transitions, hover effects, scrollbar styling, status pulse 2026-02-13 19:17:38 -06:00
2389e11469 feat: add search trigger button with ⌘K hint in navbar 2026-02-13 19:13:11 -06:00
b7204b604d fix: remove experimental badges from Alerts and Network Map nav items 2026-02-13 19:11:34 -06:00
608bad0cf6 Add What's New changelog page
- ChangelogParser: parses priv/static/changelog.txt into structured entries
- ChangelogLive: timeline view with DaisyUI styling
- Route at /changelog in authenticated scope
- What's New link in org dropdown menu
2026-02-13 19:01:19 -06:00
723f475933 feat: add global search (Cmd+K) across devices, sites, accounts, alerts
- Add Towerops.Search context module with categorized search
- Add GlobalSearchComponent LiveComponent with modal overlay
- Add GlobalSearch JS hook for Cmd+K/Ctrl+K keyboard shortcut
- Wire into authenticated layout
- Keyboard navigation (up/down/enter/esc) support
- DaisyUI-styled modal with categorized results (5 per category)
- Searches: device name/IP, site name, account name/ID, alert message
2026-02-13 18:56:15 -06:00
9c266e57ff feat: wire up Trace and Activity Feed routes + nav 2026-02-13 18:50:28 -06:00