Skip to content

refactor(source-control): unify UI state into SourceControlState - #131

Merged
ClaudiaFang merged 1 commit into
feat/source-control-integrationfrom
refactor/source-control-state-model
Aug 22, 2026
Merged

ClaudiaFang merged 1 commit into
feat/source-control-integrationfrom
refactor/source-control-state-model

Conversation

@ClaudiaFang

Copy link
Copy Markdown
Member

PR131 — Phase 2: unify state model

Stacks on PR #130 (feat/source-control-integration b3379b7). Reorganizes Source Control UI state from scattered View-local fields + direct store access into one SourceControlState container, with the ViewModel as the single facade. Pure refactor — no behavior change (all 553 tests pass).

State model (new src/logic/source-control/state/)

  • SourceControlState — thin container composing the change model + every UI state slice. Not a god-object: each slice keeps its own invariants.
  • SelectionState — moved/renamed from PushSelectionStore (same API).
  • OperationState — moved (incl. 'conflict' status from PR feat(source-control): integrate execution result and conflict status #130).
  • FilterState / ExpandedNodesState / SelectedChangeState — new slices that previously lived as View-local fields (active filter, collapsed sections/folders, selected change id).

Facade

  • SourceControlViewModel is constructed from SourceControlState and is the sole mutation surface (setFilter, toggleSection/Folder, selectForPush/deselectFromPush, selectForDiff/clearSelection, getCollapsedFolders, setOperationResult/clear). The View reaches no store directly.
  • SourceControlView holds no state and mutates only through the ViewModel; getFilter/getSelectedChangeId moved to the ViewModel. Constructor is now (viewModel, callbacks).
  • main.ts / SourceControlItemView construct SourceControlState; plugin exposes sourceControlState (replaces pushSelectionStore/operationState).
  • SourceControlFilter.matchesFilter selection param type is SelectionState.

Tests

Moved OperationState/PushSelectionStore tests into state/ (renamed SelectionState.test.ts); new FilterState/ExpandedNodesState/SelectedChangeState tests; updated ViewModel/View/ItemView/ActionService tests for the new construction.

Verification

npx eslint .   -> 0 errors
npm run build  -> PASS (tsc + Obsidian 1.11.0 compat + esbuild)
npx vitest run -> 59 files / 553 tests

Notes

PR131 / Phase 2 — reorganize Source Control UI state from scattered View-local
fields + direct store access into one SourceControlState container, with the
ViewModel as the single facade the View reads from and mutates through. Pure
refactor; no behavior change (all 553 tests pass).

State model (new src/logic/source-control/state/):
- SourceControlState: thin container composing the change model + every UI
  state slice (selection, operation, filter, expanded nodes, selected
  change). Not a god-object — each slice keeps its own invariants/methods.
- SelectionState: moved/renamed from PushSelectionStore (same API).
- OperationState: moved from src/logic/source-control/ (incl. 'conflict'
  status from PR #130).
- FilterState / ExpandedNodesState / SelectedChangeState: new slices that
  previously lived as View-local fields (active filter, collapsed
  sections/folders, selected change id).

Facade:
- SourceControlViewModel is constructed from SourceControlState and is the
  sole mutation surface (setFilter, toggleSection/Folder, selectForPush/
  deselectFromPush, selectForDiff/clearSelection, getCollapsedFolders,
  setOperationResult/clear). The View reaches no store directly.
- SourceControlView holds no state of its own and mutates only through the
  ViewModel; getFilter/getSelectedChangeId moved to the ViewModel.
  Constructor is now (viewModel, callbacks).
- main.ts / SourceControlItemView construct SourceControlState; plugin exposes
  sourceControlState (replaces pushSelectionStore/operationState).
- SourceControlFilter.matchesFilter selection param type is SelectionState.

Tests: moved OperationState/PushSelectionStore tests into state/ (renamed to
SelectionState.test.ts); new FilterState/ExpandedNodesState/SelectedChangeState
tests; updated ViewModel/View/ItemView/ActionService tests for the new
construction.

Verification: npx eslint . — 0 errors; npm run build — PASS incl. Obsidian 1.11.0
compatibility; npx vitest run — 59 files / 553 tests.
@sonarqubecloud

Copy link
Copy Markdown

@ClaudiaFang
ClaudiaFang merged commit 925a5e8 into feat/source-control-integration Aug 22, 2026
18 checks passed
@ClaudiaFang
ClaudiaFang deleted the refactor/source-control-state-model branch August 22, 2026 13:35
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