Skip to content

refactor(ios): extract data browser logic into DataBrowserViewModel#1164

Merged
datlechin merged 1 commit into
mainfrom
refactor/databrowser-viewmodel-extraction
May 9, 2026
Merged

refactor(ios): extract data browser logic into DataBrowserViewModel#1164
datlechin merged 1 commit into
mainfrom
refactor/databrowser-viewmodel-extraction

Conversation

@datlechin
Copy link
Copy Markdown
Member

Summary

P1 #5 step 1 of 3: lift business logic out of the largest iOS view (DataBrowserView, 718 LOC) into DataBrowserViewModel. The View drops down to 452 LOC and now only owns UI state (sheet flags, search input, share text, haptic triggers, navigation flags); the ViewModel owns the data lifecycle.

What moves into the ViewModel:

  • Domain state: columnDetails, foreignKeys, pagination, sortState, filters, filterLogicMode, activeSearchText, loadError, operationError, isLoading, isPageLoading, memoryWarning
  • Methods: load(isInitial:), goToNextPage, goToPreviousPage, goToPage, changePageSize, applySort, applySearch, clearSearch, applyFilters, clearFilters, deleteRow(pkValues:), primaryKeyValues(for:), fetchTotalRows, plus the SQL query construction that was inline in the View
  • A new attach(session:table:databaseType:host:) configures context once on .task. Methods take no contextual args
  • handleSystemMemoryWarning() collapses the .onReceive(UIApplication.didReceiveMemoryWarningNotification) body into a single VM call

What stays in the View:

  • Sheet/dialog/alert state (showInsertSheet, showFilterSheet, showShareSheet, showDeleteConfirmation, showStructure, showGoToPage, fkPreviewItem)
  • Pure input state (searchText, goToPageInput, shareText, deleteTarget)
  • Haptic triggers (hapticSuccess, hapticError)
  • Body composition, toolbar building, row context menu, RowDetailView and InsertRowView wiring
  • Sort menu bindings (sortColumnBinding, sortDirectionBinding) keep their custom Binding(get:set:) shape but read/write viewModel.sortState

Cleanups in the same commit:

  • The operation-error alert now binds to a derived Binding<Bool> over viewModel.operationError != nil, removing the parallel @State showOperationError and the .onChange plumbing that kept them in sync
  • rowListGeneration is gone; .id(viewModel.pagination.currentPage) is the natural identity for forcing list reset on page navigation

Test plan

  • Open a table on iPhone and iPad: initial load, columns render, row count fetches, FK indicators show on rows that have FKs
  • Pagination forward/back, "Go to Page", change page size — list resets to top each time
  • Sort a column ascending and descending — query rebuilds with ORDER BY
  • Filter sheet apply/clear — query rebuilds with WHERE
  • .searchable submit and clear — query switches between filtered and full
  • Delete a row via swipe — primary key delete fires, list reloads, success haptic
  • Delete error path (bad PK or constraint violation): operation error alert shows, error haptic
  • Memory warning: simulate via Simulator → Debug → Memory Warning. List shrinks, memory warning overlay appears, "Reload" button reloads
  • Pull to refresh
  • Share row / Copy row context menu, all formats
  • FK row context menu opens FKPreviewView
  • Insert row sheet opens; on save, list reloads

@datlechin datlechin merged commit 069e0c8 into main May 9, 2026
2 checks passed
@datlechin datlechin deleted the refactor/databrowser-viewmodel-extraction branch May 9, 2026 18:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant