feat(workflows): extend form field library and fix outer-card suppression#105
Conversation
Request: "Investigate why the workflow module doesn't render a card when the controlledList component is used on a form" — then "apply the fix". Motivation: A form whose first field is a ControlledList (or box/label/ file_upload) rendered with no card at all, and the comment input fell outside any card. The edit/error templates dropped the outer form_card whenever the first form entry declared a sub-form, on the assumption it owned its own card chrome — but of the structural components only `section` actually renders a Card. Decisions: - Key on component identity, not shape: test form[0].component == section instead of form[0].form != null. `section` is the sole card-owning structural component; the old heuristic over-triggered for controlled_list/box/label/ file_upload (none render a Card). - Minimal right-layer change inside the existing _build.if; no new machinery. Rejected adding a phone-style per-component owns_outer_chrome flag as speculative surface. Changes: - templates/edit.yaml.njk: suppression test form.0.form -> form.0.component == section - templates/error.yaml.njk: same, on form_error.0.component Note: diverges from the completed design parts/_completed/16-page-templates/ design.md:200 (which still documents the old form[0].form heuristic); left the _completed doc untouched as read-only history per repo rules. Tags: workflows, form, controlled-list, outer-card-suppression, edit-template, error-template, card, section, form-fields Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Request: Enable migrating the prp-team app to reference the workflows module on the 0.11.0 line; its form fields broke against 0.11.0's stricter block schema. Motivation: The app authored form fields as raw blocks with a stray top-level `key` (harvested into form_meta) — an off-spec "Shape-A trick" that only worked because old block validation ignored the extra property. 0.11.0 rejects it. The module's own reference mandates library components for reused fields, but the field library lacked a phone field and the disabled/extra/theme vars those fields needed. Decisions: - Contribute library components, not a resolver change: form-components.md mandates library components for reused fields, and makeActionsForm keeps emitting raw blocks verbatim. Rejected stripping `key` in the resolver — it would bless the off-spec Shape-A pattern. - phone wraps PhoneNumberInput: the form-side counterpart to the `phoneNumber` field type SmartDescriptions' view renderer already recognised (fills a real half-finished gap rather than adding speculative surface). - Additive vars only (disabled/extra on text_input, disabled/theme on button_selector) — no impact on existing consumers; yes_no_selector already carried `disabled` as precedent. - location.yaml: contentGutter -> gap; 0.11.0 promotes the deprecation to a build-failing error. Changes: - components/fields/phone.yaml: new PhoneNumberInput field component - components/fields/text_input.yaml: add disabled + extra vars - components/fields/button_selector.yaml: add disabled + theme vars - components/fields/location.yaml: layout.contentGutter -> layout.gap - apps/workflows-test/.../field-gallery/gallery.yaml: demo consumers (phone, read-only text, themed buttons) - docs/workflows/reference/form-components.md: document phone + the new vars Tags: workflows, form-components, phone, phone-number, text-input, button-selector, disabled, theme, field-library, contentgutter, deprecation, form-meta Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Saiby100
left a comment
There was a problem hiding this comment.
PR Review: #105
Linked Issues: None found
Extends the workflows form-field library (phone field + disabled/theme/extra vars) and fixes outer-card suppression to key on section identity rather than the over-broad form[0].form heuristic. Code is clean and correct — the one gap is that the plugins change has no changeset.
Verification done:
PhoneNumberInputis a real block from@lowdefy/blocks-antd— no extra plugin declaration needed. ✅disabled+themeonbutton_selectorhave in-module precedent inyes_no_selector.yaml. ✅- The view renderer already maps
PhoneNumberInput → phoneNumber(SmartDescriptions/fieldTypes/blockTypeMap.js), so the new form field is the correct counterpart. ✅
🟡 Suggestions
Missing changeset for the ContactSelector fix
File: plugins/modules-mongodb-plugins/src/blocks/ContactSelector/ContactListItem.js
Both changesets target @lowdefy/modules-mongodb-workflows only. The contact-selector alignment change lives in @lowdefy/modules-mongodb-plugins, which has no changeset.
Because .changeset/config.json sets "fixed": [["@lowdefy/modules-mongodb-*"]], the plugins package will still version-bump in lockstep — so this won't block publishing. But its CHANGELOG will carry no entry describing the fix, so consumers reading the plugins changelog won't see it.
Acceptance Criteria
| Criteria (from PR body) | Status |
|---|---|
New phone field wrapping PhoneNumberInput |
✅ valid block, follows field pattern |
Additive disabled/extra/theme vars |
✅ no impact on existing consumers |
location off deprecated contentGutter |
✅ → layout.gap in both spots |
Card suppression only for section first field |
✅ both edit + error templates, well-commented |
| All changes have changesets |
What's good: Changesets use correct semver (minor for the new field, patch for the bug fix) with clear descriptions; the suppression fix keys on component identity rather than shape and documents why the other structural components fall through.
Generated by PR Review Command
The ContactSelector action-alignment fix (2cfef7d) touched @lowdefy/modules-mongodb-plugins but shipped without a changeset, so the plugins CHANGELOG would carry no entry describing it (the fixed version group bumps the package regardless). Add a patch changeset covering the change. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Summary
Extends the workflows form field library and fixes card rendering, unblocking migration of an existing app onto the 0.11.0 module line (its form fields broke against 0.11.0's stricter block schema).
phonefield component wrappingPhoneNumberInput— the form-side counterpart to thephoneNumberfield type the view renderer already recognised.disabled+extraontext_input;disabled+themeonbutton_selector. No impact on existing consumers.location.yaml:layout.contentGutter→layout.gap(0.11.0 promotes the deprecation to a build-failing error).form_cardonly when the first field is asection(the sole card-owning structural component), instead of the oldform[0].form != nullheuristic that over-triggered forcontrolled_list/box/label/file_uploadand left them with no card.docs/workflows/reference/form-components.mdupdated.Test plan
pnpm ldf:bfromapps/democompiles clean.ControlledListnow renders inside a card.PR Checklist