Skip to content

Use project .fwlayout files for Avalonia persistence - #1111

Open
johnml1135 wants to merge 23 commits into
mainfrom
avalonia-uses-fwlayout
Open

Use project .fwlayout files for Avalonia persistence#1111
johnml1135 wants to merge 23 commits into
mainfrom
avalonia-uses-fwlayout

Conversation

@johnml1135

@johnml1135 johnml1135 commented Aug 26, 2026

Copy link
Copy Markdown
Contributor

Why

WinForms persists project layout customization in
ConfigurationSettings/*.fwlayout. Avalonia had introduced a separate
.viewoverride.json store for the same settings. Keeping both would allow the
two interfaces to disagree and would require migration and synchronization
code indefinitely.

This PR makes .fwlayout the single persistent store for both interfaces and
retires the unreleased JSON override subsystem.

Architecture

shipped layout XML + project .fwlayout
                  |
                  v
          XCore Inventory
                  |
          immutable XML snapshot
                  |
                  v
       FwAvalonia compiler/view

Avalonia command -> existing xWorks writer -> project .fwlayout -> recompose
  • Inventory remains authoritative for loading, merging, and persisting
    project layout XML.
  • A small xWorks adapter clones the effective layout into an immutable
    snapshot. FwAvalonia does not depend on XCore or retain mutable inventory
    nodes.
  • The existing compiler cache is keyed by a content fingerprint covering the
    layout, parts, class, type, and base-class map. Identical content reuses a
    compiled model; changed content produces a new model. A snapshot-construction
    counter was intentionally not retained because an arbitrary source resolver
    does not expose construction provenance.
  • Persistent menu commands identify the exact legacy slice using object, field,
    class, layout, and canonical caller path. Ambiguous or missing matches fail
    closed. Successful commands use the existing xWorks writer and then recompose
    Avalonia from Inventory.

This is an identity/provenance adapter at an existing seam, not a general
mapping or translation engine.

What changed

  • compose Avalonia detail views from the current project's effective
    Inventory layouts
  • preserve project isolation, base-class fallback, choice layouts, nested
    layouts, and content-based cache refresh
  • route Avalonia visibility and field-order commands through existing xWorks
    persistence handlers
  • remove the JSON override store, editor, differ, applier, serializer, migration
    path, and their dedicated tests
  • retain the compiled-view JSON serializer, which serves a different purpose
  • add disk-reload parity tests in both directions between WinForms and Avalonia

No customer-data migration is needed: the retired JSON persistence path has not
shipped in a FieldWorks release. Existing files created by development builds
are inert and are not deleted.

Validation

  • GitHub Flex CI: 5,737 passed, 81 skipped, 0 failed on the implementation tree
  • .\build.ps1 -CommentHygiene: passed, 0 warnings and 0 errors
  • FwAvalonia: 578 passed, 1 skipped
  • xWorks: 1,541 passed, 2 skipped
  • cross-interface persistence parity: 5 passed
  • final source/command/parity selection: 42 passed
  • final layout-choice selection: 7 passed
  • comment hygiene, commit messages, whitespace, links, and stray-docs checks:
    passed on the implementation tree

The local full-suite run also reproduced this machine's existing RootSite pixel
baseline drift and native TestViews shutdown hang; GitHub's clean run is the
authoritative cross-machine result. Interactive WinForms/Avalonia exercise was
not available in the agent environment; automated parity tests cover writes,
disk reload, reconstruction, visibility, and field ordering in both directions.

Follow-up order

Rebase #1097 and #1108 onto this change. Keep their writing-system behavior,
but remove their JSON store, JSON writers, and migration assumptions. They
should persist through the shared .fwlayout path introduced here.


This change is Reviewable

@johnml1135 johnml1135 changed the title Plan Avalonia .fwlayout convergence Use fwlayout for Avalonia layout persistence Aug 27, 2026
@github-actions

github-actions Bot commented Aug 27, 2026

Copy link
Copy Markdown

NUnit Tests

    1 files  ± 0      1 suites  ±0   10m 48s ⏱️ -4s
5 818 tests  - 43  5 737 ✅  - 43  81 💤 ±0  0 ❌ ±0 
5 827 runs   - 43  5 746 ✅  - 43  81 💤 ±0  0 ❌ ±0 

Results for commit eefbcb3. ± Comparison against base commit b8f5463.

This pull request removes 81 and adds 38 tests. Note that renamed tests count towards both.
FwAvaloniaTests.DetailOverrideRenderingTests ‑ Applier_AppliesVisibilityAndReorder_ToTheCompiledIR
FwAvaloniaTests.DetailOverrideRenderingTests ‑ DetailView_RendersOnlyTheRowsInTheModel
FwAvaloniaTests.DetailOverrideRenderingTests ‑ DetailView_RendersRowsInModelOrder_SoAReorderIsVisible
FwAvaloniaTests.ViewDefinitionOverrideApplierTests ‑ Apply_AddNode_InsertsAtParentIndex
FwAvaloniaTests.ViewDefinitionOverrideApplierTests ‑ Apply_DuplicateNode_CopiesLeafUnderNewId
FwAvaloniaTests.ViewDefinitionOverrideApplierTests ‑ Apply_DuplicateNode_SourceWithChildren_ReportsDiagnostic_AndDoesNotInsert
FwAvaloniaTests.ViewDefinitionOverrideApplierTests ‑ Apply_EmptyPatch_ReproducesBaseExactly
FwAvaloniaTests.ViewDefinitionOverrideApplierTests ‑ Apply_PreservesNodeFieldsNoOperationTouches
FwAvaloniaTests.ViewDefinitionOverrideApplierTests ‑ Apply_StalePatchTarget_IsReportedAsDiagnostic_NotFatal
FwAvaloniaTests.ViewDefinitionOverrideApplierTests ‑ RoundTrip_DiffThenApply_ReproducesCustomized_Reorder
…
FwAvaloniaTests.DetailRenderingTests ‑ DetailView_RendersOnlyTheRowsInTheModel
FwAvaloniaTests.DetailRenderingTests ‑ DetailView_RendersRowsInModelOrder_SoAReorderIsVisible
SIL.FieldWorks.XWorks.DetailCommandAdapterHardeningTests ‑ AvaloniaComposition_UsesProjectLayoutInventoryInitializedByLayoutCache
SIL.FieldWorks.XWorks.DetailCommandAdapterHardeningTests ‑ ChoosePersistentTargetSliceIndex_AmbiguousExactPath_FailsClosed
SIL.FieldWorks.XWorks.DetailCommandAdapterHardeningTests ‑ ChoosePersistentTargetSliceIndex_UsesCallerPathToDisambiguateDuplicateFields
SIL.FieldWorks.XWorks.DetailCommandAdapterHardeningTests ‑ ImportedCallerPath_IsCanonicalWhenPartsSkipOrExpandOutput
SIL.FieldWorks.XWorks.DetailComposerTests ‑ CompileForObject_RepeatContentReusesCompiledModel
SIL.FieldWorks.XWorks.DetailObjectCommandExecutionTests ‑ PersistentLayoutCommand_MissingExactIdentity_ClearsTargetAndDoesNotWrite
SIL.FieldWorks.XWorks.DetailObjectCommandExecutionTests ‑ PersistentLayoutCommand_UsesLegacyWriter_PersistsAndRecomposes("CmdAlwaysVisible","Always visible","ifdata","always")
SIL.FieldWorks.XWorks.DetailObjectCommandExecutionTests ‑ PersistentLayoutCommand_UsesLegacyWriter_PersistsAndRecomposes("CmdDataTree-MoveFieldDown","Move Down",null,"down")
…

♻️ This comment has been updated with latest results.

@codecov-commenter

codecov-commenter commented Aug 27, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 80.87774% with 61 lines in your changes missing coverage. Please review.
✅ Project coverage is 38.42%. Comparing base (b8f5463) to head (eefbcb3).

Files with missing lines Patch % Lines
...xWorks/Avalonia/Hosting/RecordEditView.Avalonia.cs 73.24% 22 Missing and 20 partials ⚠️
...n/FwAvalonia/ViewDefinition/ViewDefinitionModel.cs 78.72% 4 Missing and 6 partials ⚠️
...Avalonia/Composer/InventoryViewDefinitionSource.cs 86.66% 1 Missing and 5 partials ⚠️
Src/xWorks/Avalonia/Composer/DetailComposer.cs 92.68% 1 Missing and 2 partials ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #1111      +/-   ##
==========================================
+ Coverage   38.35%   38.42%   +0.06%     
==========================================
  Files        1507     1500       -7     
  Lines      350617   350058     -559     
  Branches    40298    40188     -110     
==========================================
+ Hits       134471   134499      +28     
+ Misses     186916   186450     -466     
+ Partials    29230    29109     -121     
Files with missing lines Coverage Δ
Src/Common/FwAvalonia/Detail/DetailModel.cs 77.95% <ø> (ø)
Src/Common/FwAvalonia/Detail/LexiconFirstSlice.cs 76.59% <100.00%> (+0.25%) ⬆️
...mon/FwAvalonia/ViewDefinition/XmlLayoutImporter.cs 88.05% <100.00%> (+2.15%) ⬆️
Src/xWorks/Avalonia/Hosting/XCoreMenuBridge.cs 79.10% <ø> (+8.95%) ⬆️
Src/xWorks/Avalonia/Composer/DetailComposer.cs 67.61% <92.68%> (+0.28%) ⬆️
...Avalonia/Composer/InventoryViewDefinitionSource.cs 86.66% <86.66%> (ø)
...n/FwAvalonia/ViewDefinition/ViewDefinitionModel.cs 87.15% <78.72%> (-1.94%) ⬇️
...xWorks/Avalonia/Hosting/RecordEditView.Avalonia.cs 62.93% <73.24%> (+17.20%) ⬆️

... and 31 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@johnml1135 johnml1135 changed the title Use fwlayout for Avalonia layout persistence Use project .fwlayout files for Avalonia persistence Aug 27, 2026
@johnml1135
johnml1135 marked this pull request as ready for review August 27, 2026 11:01
@mark-sil

Copy link
Copy Markdown
Contributor

What is the reason PR's 1097 and 1108 could not have gone in before this PR? Would it have significantly changed this PR if those were in first? Please explain why the expectation is that those PR's rebase on this PR.

@mark-sil mark-sil 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.

What is the reason PR's 1097 and 1108 could not have gone in before this PR? Would it have significantly changed this PR if those were in first? Please explain why the expectation is that those PR's rebase on this PR.

@mark-sil made 1 comment.
Reviewable status: 0 of 36 files reviewed, all discussions resolved.

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.

3 participants