- Decentralized Room Registry pattern - Each room registers itself with central registry - Dynamic navigation tabs and settings dropdown - New Media Room and Parlor feature folders - Permission-based room filtering support 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
97 lines
2.9 KiB
Dart
97 lines
2.9 KiB
Dart
import 'package:flutter/material.dart';
|
|
import 'package:go_router/go_router.dart';
|
|
import 'package:tatlock_ui/features/security/presentation/pages/security_page.dart';
|
|
import 'package:tatlock_ui/routing/app_router.dart';
|
|
import 'package:tatlock_ui/routing/room_registry.dart';
|
|
import 'package:tatlock_ui/shared/layouts/widgets/nav_panel.dart';
|
|
|
|
/// Route paths for Security room.
|
|
abstract class SecurityRoutes {
|
|
static const base = '/security';
|
|
// User Management (Authentik)
|
|
static const users = '/security/users';
|
|
static const groups = '/security/groups';
|
|
// Monitoring (future)
|
|
static const cveMonitor = '/security/cve-monitor';
|
|
static const networkMonitor = '/security/network-monitor';
|
|
static const dnsAdblock = '/security/dns-adblock';
|
|
}
|
|
|
|
/// Security room navigation items with section grouping.
|
|
enum SecurityNav {
|
|
// User Management section (moved from Control Room)
|
|
users('users', 'Users', Icons.people, 'User Management'),
|
|
groups('groups', 'Groups', Icons.group_work, 'User Management'),
|
|
// Monitoring section (placeholders for future)
|
|
cveMonitor('cve-monitor', 'CVE Monitor', Icons.security, 'Monitoring'),
|
|
networkMonitor('network-monitor', 'Network Monitor', Icons.router, 'Monitoring'),
|
|
dnsAdblock('dns-adblock', 'DNS / Adblock', Icons.dns, 'Monitoring');
|
|
|
|
const SecurityNav(this.id, this.label, this.icon, this.section);
|
|
|
|
final String id;
|
|
final String label;
|
|
final IconData icon;
|
|
final String section;
|
|
|
|
NavItem toNavItem() => NavItem(
|
|
id: id,
|
|
label: label,
|
|
icon: icon,
|
|
section: section,
|
|
);
|
|
|
|
/// Get route path for this nav item.
|
|
String get path => '/security/$id';
|
|
}
|
|
|
|
/// Get route path for a nav item.
|
|
String pathForSecurityNav(SecurityNav nav) => nav.path;
|
|
|
|
/// Security room definition.
|
|
final securityRoom = RoomDefinition(
|
|
id: 'security',
|
|
label: 'Security',
|
|
icon: Icons.security_outlined,
|
|
selectedIcon: Icons.security,
|
|
defaultRoute: SecurityRoutes.users,
|
|
routes: securityRoutes,
|
|
// No permissions required - accessible to all authenticated users
|
|
);
|
|
|
|
/// Register Security room with the room registry.
|
|
void registerSecurity() {
|
|
roomRegistry.register(securityRoom);
|
|
}
|
|
|
|
/// Security room routes for go_router.
|
|
List<RouteBase> securityRoutes() {
|
|
return [
|
|
// Redirect /security to /security/users
|
|
GoRoute(
|
|
path: SecurityRoutes.base,
|
|
name: 'security',
|
|
redirect: (context, state) => SecurityRoutes.users,
|
|
),
|
|
// Generate routes for all nav items
|
|
for (final nav in SecurityNav.values)
|
|
GoRoute(
|
|
path: nav.path,
|
|
name: 'security${_capitalize(nav.id.replaceAll('-', '_'))}',
|
|
pageBuilder: (context, state) => noTransitionPage(
|
|
context,
|
|
state,
|
|
SecurityPage(nav: nav, routerState: state),
|
|
),
|
|
),
|
|
];
|
|
}
|
|
|
|
String _capitalize(String s) {
|
|
if (s.isEmpty) return s;
|
|
return s
|
|
.split('_')
|
|
.map((part) => part[0].toUpperCase() + part.substring(1))
|
|
.join('');
|
|
}
|