Skip to content

feat: table mode full-width default, details toggle, and entity settings#184

Merged
ericgriffin merged 62 commits into
mainfrom
feature/table-mode-full-width-details-toggle
Apr 9, 2026
Merged

feat: table mode full-width default, details toggle, and entity settings#184
ericgriffin merged 62 commits into
mainfrom
feature/table-mode-full-width-details-toggle

Conversation

@ericgriffin

@ericgriffin ericgriffin commented Apr 7, 2026

Copy link
Copy Markdown
Member

Summary

Table mode full-width layout with details toggle

  • Table mode now defaults to full-width layout across all 8 entity sections (Dives, Sites, Buddies, Trips, Equipment, Dive Centers, Certifications, Courses), replacing the prior 440px MasterDetailScaffold master pane
  • New shared TableModeLayout widget 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)
  • New "Details" toggle button in the desktop app bar shows/hides the detail pane (with full edit/create support)
  • For Dives, the Details toggle is mutually exclusive with the Profile Panel toggle
  • Desktop detail page redirect now skips when in table view mode

Synchronized profile tracking

  • Shared profileTrackingIndexProvider wires the dive profile panel chart and detail page so cursor position syncs between them
  • MouseRegion.onExit clears tracking state when the cursor leaves the chart

Startup migration progress UI

  • StartupWrapper widget with splash screen, migration progress bar, and error handling
  • DatabaseService.getStoredSchemaVersion pre-check determines if migration is needed
  • MigrationProgress data model with step-by-step progress callback
  • Version mismatch and generic error screens with close/exit actions

Settings and appearance overhaul

  • Settings > Appearance reorganized as hub with per-section sub-pages (SectionAppearancePage)
  • Entity-aware ColumnConfigPage with section selector for configuring table columns, presets, and card view fields
  • Per-section "Show details pane in table mode" toggles
  • New EntityCardViewConfig<F> generic model with per-section card config providers
  • Database schema v63 adds per-section details pane persistence columns

Database and stability fixes

  • Close databases on app detach to prevent Drift isolate FFI crash
  • Use AppLifecycleListener.onExitRequested for clean database shutdown
  • Open SQLite read-only when probing schema version
  • Revert createInBackground to synchronous NativeDatabase
  • Optimize v59 pressure migration to avoid full table scans
  • Show full-page map in table view on mobile instead of split

Translations

  • Add 6 missing translation keys for appearance settings across all 10 locales

Test plan

  • 6287 tests pass, 0 failures
  • 90.3% patch coverage (2122/2351 executable lines)
  • flutter analyze -- no issues
  • dart format -- no changes needed
  • Smoke test each section in table mode on desktop: verify full-width default, details toggle, column settings button
  • Smoke test Dives: verify profile panel toggle mutual exclusion with details, synchronized cursor tracking
  • Smoke test Sites, Dive Centers: verify map + details combo layout
  • Smoke test mobile: verify details toggle is hidden, map works as before
  • Smoke test Settings > Appearance: section hub navigation, per-section settings, column config
  • Smoke test startup: verify splash screen, migration progress, error screens

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.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 TableModeLayout widget + tableDetailsPaneProvider to 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 EntityCardViewConfig model + 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.

Comment thread lib/shared/widgets/table_mode_layout/table_mode_layout.dart
Comment thread lib/shared/widgets/table_mode_layout/table_mode_layout.dart Outdated
Comment thread lib/features/settings/presentation/pages/appearance_page.dart Outdated
Comment thread lib/shared/providers/table_details_pane_provider.dart Outdated
Comment thread lib/features/settings/presentation/pages/column_config_page.dart Outdated
Comment thread lib/features/trips/presentation/pages/trip_list_page.dart
Comment thread lib/features/equipment/presentation/pages/equipment_list_page.dart
Comment thread lib/features/dive_sites/presentation/pages/site_list_page.dart
Comment thread lib/features/buddies/presentation/pages/buddy_list_page.dart
github-actions Bot and others added 2 commits April 7, 2026 14:44
…, 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>
Copilot AI review requested due to automatic review settings April 7, 2026 15:02
@ericgriffin
ericgriffin removed the request for review from Copilot April 7, 2026 15:02
@submersion-app submersion-app deleted a comment from claude Bot Apr 7, 2026
@ericgriffin ericgriffin self-assigned this Apr 7, 2026
@submersion-app submersion-app deleted a comment from claude Bot Apr 7, 2026
@submersion-app submersion-app deleted a comment from claude Bot Apr 7, 2026
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)
Copilot AI review requested due to automatic review settings April 9, 2026 05:29

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 89 out of 92 changed files in this pull request and generated 3 comments.

Comment thread lib/core/services/database_service.dart
Comment thread lib/features/dive_sites/presentation/providers/site_providers.dart
@ericgriffin

ericgriffin commented Apr 9, 2026

Copy link
Copy Markdown
Member Author

Code review

Found 2 issues:

  1. Details pane toggle changes are never persisted to the database. AppSettings defines showDetailsPaneDives, showDetailsPaneSites, etc. and DB schema v63 adds corresponding columns, but no setShowDetailsPaneForSection method exists in SettingsNotifier. Both the app bar toggle and the settings page switch only update the in-memory tableDetailsPaneProvider -- they never call settingsProvider.notifier to persist. The user's detail pane preference resets to false on every app restart. The entire persistence infrastructure (DB columns, repository mapping, AppSettings fields) is dead code.

tooltip: 'Toggle detail pane',
onPressed: () {
final newValue = !ref.read(tableDetailsPaneProvider(sectionKey));
ref.read(tableDetailsPaneProvider(sectionKey).notifier).state =
newValue;
},

value: showDetailsPane,
onChanged: (value) {
ref.read(tableDetailsPaneProvider(config.key).notifier).state = value;
},
);

  1. NativeDatabase.createInBackground regression. On main, database_service.dart uses synchronous NativeDatabase(file) with an explicit comment: "Background isolates can cause close() to hang indefinitely during migration." This PR reverts to createInBackground in the initialize() method while the reinitializeAtPath() method still uses synchronous NativeDatabase with the original warning comment intact. This reintroduces the previously-fixed hang-on-close risk during migrations.

final file = File(dbPath);
// Use createInBackground so migrations run in a separate isolate and
// do not block the main-isolate event loop. This keeps animations and
// progress-bar updates rendering smoothly while heavy DDL runs.
_database = AppDatabase(
NativeDatabase.createInBackground(file),
onMigrationProgress: onMigrationProgress,

Contrast with the warning that remains at line 127 of the same file:

final file = File(newPath);
// Use synchronous NativeDatabase instead of createInBackground to avoid
// isolate communication issues during migration
_database = AppDatabase(NativeDatabase(file));

- 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
Copilot AI review requested due to automatic review settings April 9, 2026 05:54

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot wasn't able to review this pull request because it exceeds the maximum number of lines (20,000). Try reducing the number of changed lines and requesting a review from Copilot again.

@ericgriffin ericgriffin moved this from Backlog to In review in Submersion Release Tracker Apr 9, 2026
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().
Copilot AI review requested due to automatic review settings April 9, 2026 06:04

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot wasn't able to review this pull request because it exceeds the maximum number of lines (20,000). Try reducing the number of changed lines and requesting a review from Copilot again.

- 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.
Copilot AI review requested due to automatic review settings April 9, 2026 12:24

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot wasn't able to review this pull request because it exceeds the maximum number of lines (20,000). Try reducing the number of changed lines and requesting a review from Copilot again.

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).
Copilot AI review requested due to automatic review settings April 9, 2026 20:32

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot wasn't able to review this pull request because it exceeds the maximum number of lines (20,000). Try reducing the number of changed lines and requesting a review from Copilot again.

Copilot AI review requested due to automatic review settings April 9, 2026 21:40

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot wasn't able to review this pull request because it exceeds the maximum number of lines (20,000). Try reducing the number of changed lines and requesting a review from Copilot again.

@ericgriffin
ericgriffin merged commit 1ad1092 into main Apr 9, 2026
16 checks passed
@github-project-automation github-project-automation Bot moved this from In review to Done in Submersion Release Tracker Apr 9, 2026
@ericgriffin
ericgriffin deleted the feature/table-mode-full-width-details-toggle branch April 9, 2026 22:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

2 participants