- Add Security room accessible from main navigation - Implement Users list page with DataGrid (fetches from /auth/users) - Implement Groups list page with DataGrid (fetches from /auth/groups) - Move user/group management from Control Room to dedicated Security room - Remove Authentik section from Control Room navigation 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
81 lines
2.6 KiB
Dart
81 lines
2.6 KiB
Dart
import 'package:flutter/material.dart';
|
|
import 'package:go_router/go_router.dart';
|
|
import 'package:tatlock_ui/features/control_room/presentation/pages/control_room_page.dart';
|
|
import 'package:tatlock_ui/shared/layouts/widgets/nav_panel.dart';
|
|
|
|
/// Route paths for Control Room.
|
|
abstract class ControlRoomRoutes {
|
|
static const base = '/control-room';
|
|
// Portainer
|
|
static const containers = '/control-room/containers';
|
|
static const networks = '/control-room/networks';
|
|
static const volumes = '/control-room/volumes';
|
|
static const images = '/control-room/images';
|
|
// NPM
|
|
static const proxyHosts = '/control-room/proxy-hosts';
|
|
static const redirections = '/control-room/redirections';
|
|
static const streams = '/control-room/streams';
|
|
static const certificates = '/control-room/certificates';
|
|
}
|
|
|
|
/// Control Room navigation items with section grouping.
|
|
enum ControlRoomNav {
|
|
// Portainer section
|
|
containers('containers', 'Containers', Icons.dns, 'Portainer'),
|
|
networks('networks', 'Networks', Icons.hub, 'Portainer'),
|
|
volumes('volumes', 'Volumes', Icons.storage, 'Portainer'),
|
|
images('images', 'Images', Icons.photo_library, 'Portainer'),
|
|
// NPM section
|
|
proxyHosts('proxy-hosts', 'Proxy Hosts', Icons.public, 'NPM'),
|
|
redirections('redirections', 'Redirections', Icons.alt_route, 'NPM'),
|
|
streams('streams', 'Streams', Icons.stream, 'NPM'),
|
|
certificates('certificates', 'SSL Certificates', Icons.verified_user, 'NPM');
|
|
|
|
const ControlRoomNav(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 => '/control-room/$id';
|
|
}
|
|
|
|
/// Get route path for a nav item.
|
|
String pathForNav(ControlRoomNav nav) => nav.path;
|
|
|
|
/// Control Room routes for go_router.
|
|
List<RouteBase> controlRoomRoutes() {
|
|
return [
|
|
// Redirect /control-room to /control-room/containers
|
|
GoRoute(
|
|
path: ControlRoomRoutes.base,
|
|
name: 'controlRoom',
|
|
redirect: (context, state) => ControlRoomRoutes.containers,
|
|
),
|
|
// Generate routes for all nav items
|
|
for (final nav in ControlRoomNav.values)
|
|
GoRoute(
|
|
path: nav.path,
|
|
name: 'controlRoom${_capitalize(nav.id.replaceAll('-', '_'))}',
|
|
builder: (context, state) => ControlRoomPage(nav: nav),
|
|
),
|
|
];
|
|
}
|
|
|
|
String _capitalize(String s) {
|
|
if (s.isEmpty) return s;
|
|
return s
|
|
.split('_')
|
|
.map((part) => part[0].toUpperCase() + part.substring(1))
|
|
.join('');
|
|
}
|