feat: add URL deep-linking for DataGrids
- Add PageUrlState utility for URL ↔ state serialization - Add column `id` field for unique column identification in URLs - Update idSelector to return String for URL compatibility - All DataGrid pages now support URL params: search, sort, order, id - Browser URL updates via replaceState (no GoRouter rebuilds) - Add FilterPanelSemantics for filter panel semantic IDs - Add TESTING.md documentation 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.5
parent
a6c51f757a
commit
c494ace5d8
@@ -17,11 +17,15 @@ class ControlRoomPage extends ConsumerWidget {
|
||||
const ControlRoomPage({
|
||||
super.key,
|
||||
this.nav = ControlRoomNav.containers,
|
||||
this.routerState,
|
||||
});
|
||||
|
||||
/// The current nav item to display.
|
||||
final ControlRoomNav nav;
|
||||
|
||||
/// Router state for URL deep-linking (query params).
|
||||
final GoRouterState? routerState;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
final colorScheme = Theme.of(context).colorScheme;
|
||||
@@ -53,7 +57,7 @@ class ControlRoomPage extends ConsumerWidget {
|
||||
),
|
||||
// Section content
|
||||
Expanded(
|
||||
child: _SectionContent(nav: nav),
|
||||
child: _SectionContent(nav: nav, routerState: routerState),
|
||||
),
|
||||
],
|
||||
),
|
||||
@@ -63,15 +67,16 @@ class ControlRoomPage extends ConsumerWidget {
|
||||
|
||||
/// Renders content for the selected nav item.
|
||||
class _SectionContent extends ConsumerWidget {
|
||||
const _SectionContent({required this.nav});
|
||||
const _SectionContent({required this.nav, this.routerState});
|
||||
|
||||
final ControlRoomNav nav;
|
||||
final GoRouterState? routerState;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
return switch (nav) {
|
||||
ControlRoomNav.containers => const _ContainersSection(),
|
||||
ControlRoomNav.proxyHosts => const ProxyHostsPage(),
|
||||
ControlRoomNav.containers => _ContainersSection(routerState: routerState),
|
||||
ControlRoomNav.proxyHosts => ProxyHostsPage(routerState: routerState),
|
||||
_ => _PlaceholderSection(nav: nav),
|
||||
};
|
||||
}
|
||||
@@ -119,7 +124,9 @@ class _PlaceholderSection extends StatelessWidget {
|
||||
|
||||
/// Containers section with optional stack filter.
|
||||
class _ContainersSection extends ConsumerWidget {
|
||||
const _ContainersSection();
|
||||
const _ContainersSection({this.routerState});
|
||||
|
||||
final GoRouterState? routerState;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
@@ -129,7 +136,7 @@ class _ContainersSection extends ConsumerWidget {
|
||||
return Row(
|
||||
children: [
|
||||
// Stacks filter panel
|
||||
const _StacksFilterPanel(),
|
||||
_StacksFilterPanel(routerState: routerState),
|
||||
// Divider
|
||||
VerticalDivider(
|
||||
width: 1,
|
||||
@@ -139,7 +146,7 @@ class _ContainersSection extends ConsumerWidget {
|
||||
// Main content - containers list or stack detail
|
||||
Expanded(
|
||||
child: selectedStack == null
|
||||
? const ContainersListPage()
|
||||
? ContainersListPage(routerState: routerState)
|
||||
: StackDetailPage(stackId: selectedStack),
|
||||
),
|
||||
],
|
||||
@@ -149,7 +156,9 @@ class _ContainersSection extends ConsumerWidget {
|
||||
|
||||
/// Stacks filter panel for Containers section (includes "All Containers" option).
|
||||
class _StacksFilterPanel extends ConsumerWidget {
|
||||
const _StacksFilterPanel();
|
||||
const _StacksFilterPanel({this.routerState});
|
||||
|
||||
final GoRouterState? routerState;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
@@ -207,6 +216,7 @@ class _StacksFilterPanel extends ConsumerWidget {
|
||||
data: (stacks) => _StacksList(
|
||||
stacks: stacks,
|
||||
selectedStackId: selectedStack,
|
||||
routerState: routerState,
|
||||
onStackSelected: (id) =>
|
||||
ref.read(selectedStackProvider.notifier).select(id),
|
||||
onStackAction: (id, action) =>
|
||||
@@ -281,12 +291,14 @@ class _StacksList extends StatefulWidget {
|
||||
required this.selectedStackId,
|
||||
required this.onStackSelected,
|
||||
required this.onStackAction,
|
||||
this.routerState,
|
||||
});
|
||||
|
||||
final List<Stack> stacks;
|
||||
final String? selectedStackId;
|
||||
final void Function(String) onStackSelected;
|
||||
final void Function(String, String) onStackAction;
|
||||
final GoRouterState? routerState;
|
||||
|
||||
@override
|
||||
State<_StacksList> createState() => _StacksListState();
|
||||
|
||||
Reference in New Issue
Block a user