feat: table mode full-width default, details toggle, and entity settings#184
Conversation
Add per-section details pane toggle support for table mode: - StateProvider.family keyed by section name (dives, sites, etc.) - 8 new boolean columns in diverSettings table (v63 migration) - AppSettings fields and repository mapping for persistence
Shared ConsumerWidget that encapsulates the layout state machine for table mode across all entity sections (Dives, Sites, Buddies, etc.). Manages toggling between full-width table, table+detail pane (MasterDetailScaffold), table+map side-by-side, and table+profile panel layouts. Profile and Details are mutually exclusive.
Replace the ad-hoc table mode layout in DiveListPage with the shared TableModeLayout widget. This consolidates the profile panel, map toggle, detail pane, and column settings into TableModeLayout's state machine, removing ~100 lines of duplicated layout logic from DiveListContent. - Remove _buildTableMapView from DiveListPage (logic now in TableModeLayout) - Replace table mode branch with single TableModeLayout widget call - Simplify _buildTableModeScaffold to only provide embedded content - Remove DiveProfilePanel from _buildTableView (managed by TableModeLayout) - Remove duplicate map toggle from compact app bar in table mode - Update test comments to reflect profile panel ownership change
Sites table mode now uses the shared TableModeLayout widget instead of managing its own standalone Scaffold/AppBar. Column settings, map toggle, and detail pane toggle are all handled by TableModeLayout. The content widget provides only the compact app bar (search, filter, sort) and the table view itself.
Dive Centers table mode now uses the shared TableModeLayout widget instead of managing its own standalone Scaffold/AppBar. Column settings, map toggle, and detail pane toggle are all handled by TableModeLayout. The content widget provides only the compact app bar (search, sort) and the table view itself.
Move table mode orchestration (app bar, column settings, detail pane) from BuddyListContent to TableModeLayout in BuddyListPage. Simplify _buildTableModeScaffold to only provide compact bar + table content. Add highlightedBuddyIdProvider for table mode selection tracking.
Move table mode orchestration (app bar, column settings, detail pane) from TripListContent to TableModeLayout in TripListPage. Simplify _buildTableModeScaffold to only provide compact bar + table content. Add highlightedTripIdProvider for table mode selection tracking.
Move table mode orchestration (app bar, column settings, detail pane) from EquipmentListContent to TableModeLayout in EquipmentListPage. Table mode intercepts before the tab scaffold, showing only the Equipment items table. Simplify _buildTableModeScaffold to only provide compact bar + filter chips + table content. Add highlightedEquipmentIdProvider for table mode selection tracking.
Move table mode orchestration (app bar, column settings, detail pane) from CertificationListContent to TableModeLayout in CertificationListPage. Remove column settings from compact bar since TableModeLayout now manages them. Add highlightedCertificationIdProvider for table mode selection tracking.
Move table mode orchestration (app bar, column settings, detail pane) from CourseListContent to TableModeLayout in CourseListPage. Remove column settings from compact bar since TableModeLayout now manages them. Add highlightedCourseIdProvider for table mode selection tracking.
Add a Section dropdown (Dives, Sites, Buddies, Trips, Equipment, Dive Centers, Certifications, Courses) above the view mode dropdown. Dives continues to use its existing config widgets; all other sections use new generic _EntityTableConfigSection and _EntityCardConfigSection widgets that work with EntityTableViewConfig<F> and EntityCardViewConfig<F>. Certifications and Courses restrict available modes to Table + Detailed.
Add per-section SwitchListTile toggles for all 8 entity sections (Dives, Sites, Buddies, Trips, Equipment, Dive Centers, Certifications, Courses) that control the default state of the details pane in table mode. Uses the existing tableDetailsPaneProvider family provider.
Fixes prefer_const_declarations lint in entity_card_view_config_test.dart by converting variable declaration to const and removing redundant inner const.
There was a problem hiding this comment.
Pull request overview
This PR introduces a shared “table mode” layout system to make entity tables full-width by default on desktop, with an optional right-side details pane toggle (and map/profile panel support where applicable). It also expands Appearance settings to support entity-aware column/card configuration and adds DB fields intended to persist per-section details-pane visibility.
Changes:
- Added a shared
TableModeLayoutwidget +tableDetailsPaneProviderto control full-width table vs master-detail details pane (and map/profile combinations). - Extended settings UI/tests for entity-aware column configuration (section selector) and details-pane toggles for 8 entity sections.
- Added generic
EntityCardViewConfigmodel + per-entity card/table config providers and a DB migration (schema v63) for per-section details-pane persistence.
Reviewed changes
Copilot reviewed 44 out of 44 changed files in this pull request and generated 10 comments.
Show a summary per file
| File | Description |
|---|---|
| test/shared/widgets/table_mode_layout/table_mode_layout_test.dart | New widget tests for TableModeLayout toggles and mutual exclusion. |
| test/shared/providers/table_details_pane_provider_test.dart | New unit tests for per-section details-pane provider. |
| test/shared/models/entity_card_view_config_test.dart | New unit tests for generic card view config JSON/copy/equality. |
| test/features/trips/presentation/widgets/trip_list_content_test.dart | Removes assertions tied to old per-content table app bar behavior. |
| test/features/settings/presentation/pages/column_config_page_test.dart | Adds coverage for section selector and per-section mode availability. |
| test/features/settings/presentation/pages/appearance_page_test.dart | Adds coverage for new details-pane toggle section. |
| test/features/equipment/presentation/widgets/equipment_list_content_test.dart | Updates tests for removal of table app bar controls from content widget. |
| test/features/dive_sites/presentation/widgets/site_list_content_table_test.dart | Updates tests to reflect map/column settings now handled by layout. |
| test/features/dive_log/presentation/widgets/dive_list_content_test.dart | Updates tests for profile panel now being owned by TableModeLayout. |
| test/features/dive_centers/presentation/widgets/dive_center_list_content_test.dart | Updates tests to reflect layout-managed map/column settings. |
| test/features/courses/presentation/widgets/course_list_content_test.dart | Updates tests for layout-managed column settings and compact bar semantics. |
| test/features/certifications/presentation/widgets/certification_list_content_test.dart | Updates tests for layout-managed column settings and compact bar semantics. |
| test/features/buddies/presentation/widgets/buddy_list_content_test.dart | Updates tests for removal of table app bar controls from content widget. |
| lib/shared/widgets/table_mode_layout/table_mode_layout.dart | New shared layout widget implementing full-width table + optional detail/map/profile. |
| lib/shared/providers/table_details_pane_provider.dart | New per-section StateProvider for details-pane visibility. |
| lib/shared/models/entity_card_view_config.dart | New generic card-slot + card-view config model for non-dive entities. |
| lib/features/trips/presentation/widgets/trip_list_content.dart | Removes table-mode Scaffold/app bar; table mode now returns compact bar + table only. |
| lib/features/trips/presentation/providers/trip_providers.dart | Adds highlighted ID + default card configs for Trips. |
| lib/features/trips/presentation/pages/trip_list_page.dart | Routes table mode through TableModeLayout and moves column settings action into layout. |
| lib/features/settings/presentation/providers/settings_providers.dart | Adds AppSettings fields for per-section details-pane defaults (intended persistence). |
| lib/features/settings/presentation/pages/column_config_page.dart | Adds section selector and generic entity table/card config sections. |
| lib/features/settings/presentation/pages/appearance_page.dart | Adds “Show details pane in table mode” toggles for 8 sections. |
| lib/features/settings/data/repositories/diver_settings_repository.dart | Persists new per-section details-pane settings to/from DB. |
| lib/features/equipment/presentation/widgets/equipment_list_content.dart | Removes table-mode Scaffold/app bar; defers layout controls to TableModeLayout. |
| lib/features/equipment/presentation/providers/equipment_providers.dart | Adds highlighted ID + default card configs for Equipment. |
| lib/features/equipment/presentation/pages/equipment_list_page.dart | Routes Equipment table mode through TableModeLayout and moves column settings action into layout. |
| lib/features/dive_sites/presentation/widgets/site_list_content.dart | Removes table-mode Scaffold/app bar; map toggle now suppressed in table mode. |
| lib/features/dive_sites/presentation/providers/site_providers.dart | Adds highlighted ID + default card configs for Sites. |
| lib/features/dive_sites/presentation/pages/site_list_page.dart | Routes Sites table mode through TableModeLayout (map + column settings in layout). |
| lib/features/dive_log/presentation/widgets/dive_list_content.dart | Removes table-mode Scaffold/profile panel from content; table mode now “embed-only”. |
| lib/features/dive_log/presentation/pages/dive_list_page.dart | Routes Dives table mode through TableModeLayout (map/profile/details + columns in layout). |
| lib/features/dive_centers/presentation/widgets/dive_center_list_content.dart | Removes table-mode Scaffold/app bar; map toggle suppressed in table mode. |
| lib/features/dive_centers/presentation/providers/dive_center_providers.dart | Adds highlighted ID + default card configs for Dive Centers. |
| lib/features/dive_centers/presentation/pages/dive_center_list_page.dart | Routes Dive Centers table mode through TableModeLayout (map + columns in layout). |
| lib/features/courses/presentation/widgets/course_list_content.dart | Removes table-mode Scaffold/app bar; defers column settings to layout. |
| lib/features/courses/presentation/providers/course_providers.dart | Adds highlighted ID + default card config for Courses. |
| lib/features/courses/presentation/pages/course_list_page.dart | Routes Courses table mode through TableModeLayout and moves column settings into layout. |
| lib/features/certifications/presentation/widgets/certification_list_content.dart | Removes table-mode Scaffold/app bar and compact-bar column settings. |
| lib/features/certifications/presentation/providers/certification_providers.dart | Adds highlighted ID + default card config for Certifications. |
| lib/features/certifications/presentation/pages/certification_list_page.dart | Routes Certifications table mode through TableModeLayout and moves column settings into layout. |
| lib/features/buddies/presentation/widgets/buddy_list_content.dart | Removes table-mode Scaffold/app bar; defers layout controls to TableModeLayout. |
| lib/features/buddies/presentation/providers/buddy_providers.dart | Adds highlighted ID + default card configs for Buddies. |
| lib/features/buddies/presentation/pages/buddy_list_page.dart | Routes Buddies table mode through TableModeLayout and moves column settings into layout. |
| lib/core/database/database.dart | Bumps schema to v63 and adds diver_settings columns for per-section details-pane persistence. |
Codecov Report❌ Patch coverage is 📢 Thoughts on this report? Let us know! |
…, equipment, sites, and dive centers Adds mobile-mode widget tests for the 6 list pages that had 0% patch coverage in the PR. Each file covers mobile rendering, loading state, empty state, FAB label, and (where applicable) data display — targeting the page-level branch coverage gap reported by Codecov. Co-authored-by: Eric Griffin <ericgriffin@users.noreply.github.com>
Add missing diver_providers.dart import (currentDiverIdProvider) and buddy_repository.dart import (BuddyWithDiveCount) to 6 test files. Fix use_super_parameters warnings in mock notifier constructors. Co-authored-by: Eric Griffin <ericgriffin@users.noreply.github.com>
Add ~80 tests across 10 new and 4 modified test files to improve patch coverage from 37% toward 90% for PR #184. - List page layout branch tests for all 8 entity sections (mobile/table/desktop modes) - AppSettings copyWith and defaults for new showDetailsPane* fields - Runtime view mode provider unit tests (6 providers) - Appearance page interaction tests (toggles, dropdowns) - Highlighted entity ID provider tests (7 providers)
Add comprehensive test coverage for the table-mode-full-width-details-toggle feature across 7 test files (+1149 lines, -139 lines): - New: profile_tracking_provider_test.dart (5 tests, was 0% covered) - Expanded: table_details_pane_provider_test.dart (all 8 section keys) - Expanded: settings_providers_details_pane_test.dart (computed getters, unitPreset, gfDisplay, showDepthColoredDiveCards) - Expanded: entity_card_view_config_test.dart (empty collection edge cases) - Expanded: section_appearance_page_test.dart (36 tests covering all 8 sections, dropdowns, toggles, callbacks, conditional sections) - Expanded: startup_page_test.dart (16 tests covering splash, migration progress, version mismatch error, generic error, close button) - Expanded: table_mode_layout_test.dart (mobile map full-page, column settings action, vertical divider, profile-only layout, section keys)
Code reviewFound 2 issues:
submersion/lib/shared/widgets/table_mode_layout/table_mode_layout.dart Lines 304 to 309 in fc4047e
submersion/lib/core/services/database_service.dart Lines 97 to 103 in fc4047e Contrast with the warning that remains at line 127 of the same file: submersion/lib/core/services/database_service.dart Lines 126 to 129 in fc4047e |
- Add setShowDetailsPaneForSection to SettingsNotifier so details pane toggle persists to DB (was only updating in-memory provider) - Wire both app bar toggle and settings page switch to persist - Guard profile toggle on onProfileToggled != null (was rendering interactive button with no callback) - Change ref.read to ref.watch for siteListViewModeProvider in build path - Make _closeApp async with best-effort DB close before exit - Update stale doc comments on _buildTableModeScaffold in 3 list content files to match actual implementation - Localize hard-coded strings in appearance and section appearance pages using new l10n keys and existing nav_* keys
Avoids creating WAL/journal side-effect files when only reading PRAGMA user_version for the pre-migration step count check.
Reverts the initialize() method back to synchronous NativeDatabase, matching reinitializeAtPath() and the prior intentional fix. Background isolates can cause close() to hang indefinitely if called mid-migration. Progress bar updates still render between migration steps via the Future.delayed(Duration.zero) yield in reportProgress().
- appearance_page_test: update expected section label from "Dive Sites" to "Sites" to match nav_sites l10n key - table_mode_layout_test: add explicit setShowDetailsPaneForSection override to mock notifier (noSuchMethod fallback can't handle it)
Add 6 untranslated keys (settings_appearance_general, sections, showDetailsPane, showDetailsPane_subtitle, showProfilePanel, showProfilePanel_subtitle) to ar, de, es, fr, he, hu, it, nl, pt, zh.
Add ~220 tests across 32 files covering table mode toolbar buttons, detail/edit/create builder closures, desktop redirect logic, startup page lifecycle, settings navigation, import wizard file pickers, device detail page, dive profile panel pointer tracking, and settings provider methods.
Accept deletion of fit_adapter_test.dart and uddf_file_picker_step_test.dart since the underlying source files were removed on main. Update device_detail_page_test.dart for simplified API (no DiveComputerStats).
Summary
Table mode full-width layout with details toggle
TableModeLayoutwidget manages the layout state machine: full-width table (default), optional details pane via MasterDetailScaffold, optional map side-by-side, and profile panel support (Dives only)Synchronized profile tracking
profileTrackingIndexProviderwires the dive profile panel chart and detail page so cursor position syncs between themMouseRegion.onExitclears tracking state when the cursor leaves the chartStartup migration progress UI
StartupWrapperwidget with splash screen, migration progress bar, and error handlingDatabaseService.getStoredSchemaVersionpre-check determines if migration is neededMigrationProgressdata model with step-by-step progress callbackSettings and appearance overhaul
SectionAppearancePage)ColumnConfigPagewith section selector for configuring table columns, presets, and card view fieldsEntityCardViewConfig<F>generic model with per-section card config providersDatabase and stability fixes
AppLifecycleListener.onExitRequestedfor clean database shutdowncreateInBackgroundto synchronousNativeDatabaseTranslations
Test plan
flutter analyze-- no issuesdart format-- no changes needed