refactor(views): retire the duplicate SIMPLE layout example from the lead showcase - #1718
Merged
Merged
Conversation
…lead showcase `src/views/lead.view.ts` declares itself a UI showcase whose `formViews` block carries one example per FormView layout type. `quick_create`'s own numbered comment named what it demonstrated — the SIMPLE layout, "already shown as default form above" — so it was the one entry the set could lose without losing a layout. Every remaining named form is still the only example of its own layout, and the file still covers all six. It is also unreachable, but that is why the removal is free rather than why it happens: on the pinned 17.3.0 bundle both surfaces that open a lead create form resolve `view.form ?? view.formViews.default`, and `crm_lead` declares `form`. No user-visible surface changes — no form, no field, no label, no route. Its four-locale section heading (`crm_lead._sections.lead_details`) goes with it: that key had no other source, and `objectstack lint` reports it as `translation-target-unknown` in all four locales once the source is gone, while `pnpm verify` stays green regardless. Total lint issues return to the pre-change count of 13. Also corrected, as the same fact seen from elsewhere: the `formViews` block comment, the LEA-015 row of `docs/feature-inventory.md` (8 named forms -> 7), and a scope note in `test/metadata-references.test.ts` that used the deleted entry as its example. Co-authored-by: Claude
|
The latest updates on your projects. Learn more about Vercel for GitHub. |
os-steve
marked this pull request as ready for review
September 6, 2026 13:12
This was referenced Sep 6, 2026
8 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #1707
Description
src/views/lead.view.tsopens by declaring itself a UI showcase — item 1 ofits own file header is "All 6 FormView layout types (simple, tabbed, wizard,
split, drawer, modal)" — and each entry in its
formViewsblock carries anumbered comment saying which layout it is the example of.
So "nothing can reach it" is not why
quick_creategoes. By that argumentmost of its siblings would go with it: on the measurement below, no named form
view on
crm_leadis reachable. Deleting one member of a self-declared showcasebecause it is unreachable, while leaving the equally unreachable rest, is not a
cleanup — it is an unruled sweep, decided one entry at a time.
What makes
quick_createdifferent is written in its own comment:In a set whose organising principle is one example per layout, that is the
duplicate exhibit. The layout it demonstrates is demonstrated by the default
form, which declarestype: 'simple'. Remove it and the showcase stillcovers all six layout types; remove any sibling and it loses one — each of
detail_form(tabbed),lead_conversion_wizard(wizard),split_edit(split),quick_edit_drawer(drawer) andstatus_update_modal(modal) is the onlyexample of its own.
Unreachability is why the removal is free, not why it happens. That
distinction is the whole content of this PR's ruling, and it is why this is not
a precedent for deleting anything else in the file.
Changes Made
src/views/lead.view.ts— deleteformViews.quick_createand its numberedcomment. Nothing else in the file changes except the
formViewsblock comment,which now states the organising principle (one example per layout, SIMPLE being
the default
form) so the next reader does not have to re-derive it. The sharedDUPLICATE_LINK_FIELDSconstant is untouched —quick_createwas one of eightusers. The default
formis untouched; it already carries those eight fieldsand roughly twelve more.
src/translations/{en,zh-CN,ja-JP,es-ES}/objects.pipeline.ts— dropcrm_lead._sections.lead_details, the section heading whose only source was thedeleted form. See the i18n measurement below.
docs/feature-inventory.md— LEA-015 said "8 named forms"; it is 7.test/metadata-references.test.ts— a scope note usedquick_createas itsexample of a named form that still carries a
datablock. It named a form thatno longer exists; the example is now
lead_conversion_wizard/split_edit,both of which do.
The last three are the same fact seen from elsewhere, not extra scope.
Measurements
1. Reachability, re-verified on the pinned 17.3.0 bundle
Against
node_modules/@objectstack/console/dist/assets:RecordFormPage-CGQlYWDk.jsH.form ?? H.formViews?.default ?? {}useActionModal-CkM-zGdy.jse?.form ?? e?.formViews?.defaultRecordDetailView-A8bbPnkK.jsformViews?.default?.subformsindex-BU-FzlQ6.jse.formViews[n] = i— a write, in the stored-view normalizerNo read is keyed by an authored name.
crm_leaddeclaresform, soformwinsand no named form view is consulted. Enumerating every
.viewproperty read inthe entire bundle returns exactly three, none of which resolves a form view.
One card premise did not survive this. #1707 listed
navigation.viewas theone path that is reached, and concluded
detail_formwas live. It is not:navigation.viewis read once and passed as the second argument ofonNavigate— the navigation mode slot, whose consumer compares it against
`edit`and
`view`. Filed as #1716 rather than fixed here: different key,different blast radius, and telling "inert" from "row click does nothing" needs
a browser.
This does not move the ruling, because the ruling never rested on reachability.
And it triggers no widening: the stop-and-report condition was a sibling that is
both unreachable and a duplicate layout example. None is.
web_to_leadandadvanced_conditionalare alsotype: 'simple', but neither is a numberedlayout slot — they are the file's only examples of public/anonymous sharing and
of conditional field visibility respectively, which are items 2 and 3 of the
file's own showcase list.
2. i18n orphan keys — the difference set is four, and it is not empty
Deleting the form deletes the source of its section name
lead_details, whoseonly other occurrence in
src/is arecord:detailscomponent id on thedetail page — a different keyspace (
pages.*.components.*, which declares nolead_details), not a section name.Measured by running
objectstack lint --jsonon the tree atHEADand againwith only the form deleted:
passedHEAD)truetruetrueThe four introduced were exactly one per locale:
#1262's warning holds, and its wording needs one correction.
pnpm verifystays green with those four dead keys in the tree —
passed: true, lint exits 0on warnings, and
check-lint-i18n-gate.mjsgates only oni18n/missing-*, whichtranslation-target-unknownis not. So green is indeed no evidence of noorphans, exactly as #1262 says. But the check itself is not absent: the
platform's own lint reports each one by path and even suggests the fix ("or drop
the translation"). #1262's claim that orphaned keys are "invisible to every i18n
check" is too strong for this surface — they are visible, and ungated. Worth a
line on that card; it changes the shape of the fix from "write a new check" to
"gate the one that exists".
They are removed here rather than reported and left, on this repo's own
precedent: #1262 records that PR #1261 removed its four orphans by hand for the
same reason. Removing them cannot change a rendered surface — lint's own message
is that the heading "stays in the source locale", i.e. the key resolves nothing —
and had the deletion been wrong, the surface-to-translation direction of
test/i18n-references.test.tswould have gone red. It did not.3. Pin surface — checked before editing, not after
test/walksformViewsin five places, all generically. None namesquick_create, and no assertion pins a form-view count or name list. The"guards the guard" floors are
forms.lengthandoffersReason.lengthgreaterthan 3; the lead form family goes 9 to 8 and the disqualification subset 8 to
7. No pin was relaxed, and none went red — 3408 tests pass.
4. Docs surface — swept by behaviour, not by token
Searching the token
quick_createfinds five decoys and one hit that matters:the four locale
pages.sales_home_page.components.quick_createkeys andsrc/pages/home.page.tsare the home page's Quick Create card, an unrelatedpage:cardthat stays. Searching by behaviour instead (快速新建,线索表单,"quick capture", "8 fields", and the same in the other locales) found the one
piece of prose that this change falsifies:
docs/feature-inventory.mdLEA-015,which counts the family. That row is corrected here.
Three other "quick-create" mentions (
lead.object.ts,task.object.ts,event.object.ts,event_attendee.view.ts) describe the console's genericcreate dialog, not this form view, and are left alone.
Separately, all four locale bundles carry a comment claiming
crm_leadhas "sixnamed formViews". It had eight before this change and has seven after — wrong on
both sides, so it is pre-existing drift this PR did not create and does not fix.
Filed as #1717.
5. Neither in-flight surface is touched
No file in this diff belongs to #1214 item 4 (the quote family —
crm_quotetranslations live in
objects.commerce.ts, not theobjects.pipeline.tsthisPR edits) or to #1692 (
src/data/sales.seed.ts).6. Token ratchet
Removal only widens headroom, as expected — the numbers, not the assumption:
The measure is comment-stripped, so the added block comment costs nothing and the
locale edits are outside the ratchet by ruling.
Changeset:
patch, derived from this repo's own removalsLevel was chosen by counting, not by feel. Of 206 changesets, 111 declare
'hotcrm': patch, 7minor, and 88 use the sanctioned empty frontmatter. Eightof them open with Remove / Retire / Delete / Drop:
remove-knowledge-review-queue-tabremove-product-default-tax-ratea-tab-is-a-viewlist.tabs[]— view keys the console does not readtab-labels-live-on-the-viewtabs[].label, for the same reasoncsat-was-declared-never-enforcedproduct-rows-name-what-the-catalog-hasanalytics-docs-drop-the-dataset-inventoryretire-stackblitz-and-the-npm-lockfileThe split is by visible surface, not by diff size: the two
minorremovalseach took something off a screen; every
patchremoval took away metadata noscreen rendered — including #1428, which removed two fields, a flow, four
locales' labels and three doc locales' prose and still took
patch.This change removes metadata no screen rendered, so:
patch. The emptyfrontmatter form was not used because that one is for PRs that ship nothing
(
test/header notes, prose), and this one changessrc/metadata that ships inthe built artifact.
Testing
pnpm verifyran to completion with exit code 0. Each stage's real result, readfrom the log rather than assumed:
validate✓ Validation passed (1325ms)typechecktsc --noEmit, no diagnosticslint1 warning(s), 12 suggestion(s)— the pre-change count, unchangedlint:i18n-gate✓ i18n lint gate: 0 i18n/missing-* issues (13 total lint issue(s) reported)hygiene✓ source hygiene cleanhygiene:tokens✓ source token ratchet clean(three ceilings green)buildArtifact: dist/objectstack.json (1906.0 KB)testTest Files 161 passed (161)·Tests 3408 passed, 1 skipped (3409)The lint row is the one worth reading twice: the count returns to the
pre-change 13, which is the evidence that this change leaves no orphaned key
behind rather than merely passing a gate that cannot see them.
Acceptance
form(andweb_to_lead/advanced_conditional); tabbed, wizard, split,drawer and modal each still have their sole example.
This is the half that separates this card from Retire
crm_case.customer_rating/customer_feedbackunder ADR-0049, and retire or rewritecase_csat_followupwith them (ruled A, 2026-09-03; theinternal_noteshalf landed in PR #1506) #1428, where the removal didcost visible capability and went to the maintainer.
Out of scope, filed rather than ridden along
navigation.view: 'detail_form'is not a form-view name to console 17.3.0 — it lands in the navigation MODE slot #1716 —crm_leadlistnavigation.view: 'detail_form'is read as anavigation mode, not a form-view name.
crm_leadhas "six named formViews" — it has seven, and had eight #1717 — the four locale bundles' "six named formViews" comment.Generated by Claude Code