Skip to content

fix(pages): honour DataView FormOrientation and showFooter (#762, #813) - #75

Merged
ako merged 1 commit into
mainfrom
claude/dataview-762-813
Aug 1, 2026
Merged

fix(pages): honour DataView FormOrientation and showFooter (#762, #813)#75
ako merged 1 commit into
mainfrom
claude/dataview-762-813

Conversation

@ako

@ako ako commented Aug 1, 2026

Copy link
Copy Markdown
Owner

Fixes mendixlabs#762 and mendixlabs#813.

Two DataView properties parsed, passed mxcli check, and were then silently discarded. Same symptom, different causes — worth reading as two fixes that happen to share a file.

mendixlabs#762FormOrientation: Vertical had no effect on the default engine

It worked under --engine legacy and was dropped on the default (modelsdk) one:

engine LabelWidth in BSON
legacy [0, 3]
modelsdk (default) [] — absent ❌

Studio Pro's "Form orientation" radio has no BSON field of its own — it is LabelWidth (0 = Vertical, 3 = Horizontal, Mendix's metamodel default). Only the legacy writer performed that translation. The modelsdk writer emitted LabelWidth solely when an explicit LabelWidth: was given, so the orientation was read into the model and then dropped.

That is the mendixlabs#812 shape again: a field set on the model that no writer on the active engine reads. The derivation now lives on the model (pages.DataView.ResolvedLabelWidth) and both writers call it, so they cannot drift apart a second time; the modelsdk writer emits LabelWidth unconditionally.

mendixlabs#813showFooter was not settable at all

ShowFooter was only ever set implicitly, by the presence of a footer { … } block. So there was no way to show an empty footer, and no way to declare footer widgets that start hidden. The property sits in the validator's allow-list, so showFooter: true parsed clean and was thrown away.

It is now read explicitly and wins over the block in both directions; hiding a footer does not discard its widgets.

A trap worth flagging for reviewers

WidgetV3.GetBoolProp is case-sensitive and accepts only a real bool — unlike GetStringProp, which is case-insensitive. My first attempt found the key and still read false. The value is now coerced from the looked-up value, and a nonsense one is refused rather than defaulting to false — defaulting is precisely the failure mode this fix is closing. Same hazard exists for any other property read with GetBoolProp.

Verification

End-to-end against a real project, both engines now producing identical BSON:

LabelWidth   [0, 3, 5, 3]                 (Vertical, Horizontal, explicit 5, default)
ShowFooter   [false, false, false, true]

And DESCRIBE round-trips all four forms:

dataview dvVert     (DataSource: $Thing, FormOrientation: Vertical)
dataview dvHoriz    (DataSource: $Thing)                     -- 3 is the default, omitted
dataview dvExplicit (DataSource: $Thing, LabelWidth: 5)
dataview dvFoot     (DataSource: $Thing, ShowFooter: true)

ShowFooter is emitted only when the implicit rule would not reproduce the stored value, so a plain footer block still round-trips as a block rather than gaining a redundant property.

Mutation-checked: reverting the mendixlabs#762 fix fails 1 case, reverting mendixlabs#813 fails 6. Full suite green; corpus at 237/39 (+1 for the new repro fixture).

Docs: create-page.md gains the showFooter section; a symptom row is appended at the end of the table, per the convention added in #70.

🤖 Generated with Claude Code

https://claude.ai/code/session_012XR649rKk68z6gBpngu6MA


Generated by Claude Code

…s#762, mendixlabs#813)

Two DataView properties parsed, passed `mxcli check`, and were then silently
discarded. Different causes, identical symptom.

mendixlabs#762 — FormOrientation: Vertical had no effect on the DEFAULT (modelsdk) engine,
while working under --engine legacy. Studio Pro's "Form orientation" radio has
no BSON field of its own: it IS LabelWidth (0 = Vertical, 3 = Horizontal,
Mendix's metamodel default). Only the legacy writer performed that translation;
the modelsdk writer emitted LabelWidth solely when an explicit `LabelWidth:` was
given, so the orientation was read into the model and dropped. That is the mendixlabs#812
shape again — a field set on the model that no writer on the active engine
reads.

The derivation now lives on the model (pages.DataView.ResolvedLabelWidth) and
both writers call it, so they cannot drift apart again; the modelsdk writer emits
LabelWidth unconditionally.

mendixlabs#813 — showFooter was not settable at all. ShowFooter was only ever set
implicitly, by the presence of a `footer { … }` block, so there was no way to
show an empty footer or to declare footer widgets that start hidden. The property
sits in the validator's allow-list, so it parsed clean and was thrown away. It is
now read explicitly and wins over the block in both directions; hiding a footer
does not discard its widgets.

A trap worth recording: WidgetV3.GetBoolProp is case-SENSITIVE and accepts only a
real bool, unlike GetStringProp which is case-insensitive. My first attempt found
the key and still read false, so the value is now coerced from the looked-up
value and a nonsense one is refused rather than defaulting to false — defaulting
is the failure mode this whole fix is closing.

DESCRIBE emits ShowFooter only when the implicit rule would not reproduce the
stored value, so a plain footer block still round-trips as a block.

Verified end-to-end against a real project, both engines producing identical BSON:

  LabelWidth  [0, 3, 5, 3]           (Vertical, Horizontal, explicit 5, default)
  ShowFooter  [false, false, false, true]

and DESCRIBE round-trips all four forms. Reverting either fix fails the new
tests: 1 case for mendixlabs#762, 6 for mendixlabs#813.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012XR649rKk68z6gBpngu6MA
@ako
ako merged commit 2445f3e into main Aug 1, 2026
3 checks passed
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.

DATAVIEW - FormOrientation: Vertical doesn't work

2 participants