Repository navigation
feat(visual-builder): edit Select fields from the canvas toolbar - #668
Conversation
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
✅ Snyk checks have passed. No issues have been found so far.
💻 Catch issues earlier using the plugins for VS Code, JetBrains IDEs, Visual Studio, and Eclipse. |
🔒 Security Scan Results
⏱️ SLA Breach Summary
✅ BUILD PASSED - All security checks passed |
Coverage Report
File Coverage
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
hitesh-shetty-cstk
left a comment
There was a problem hiding this comment.
Automated review
What this changes: The canvas toolbar now offers Edit on Select fields and routes them to the field edit modal. getFieldType reclassifies number dropdowns from Number to Select, which also stops them being typed into inline and bypassing the choice list. A multiple Select is treated as one field: value clicks lose the move and delete buttons, and no add buttons are drawn around it.
Business impact: Inline editing on the canvas for Select fields. Two things to weigh. The Visual Editor side has no Select control in the modal yet, so on this branch Edit opens a modal with nothing to edit; the PR description already gates the release on that. Separately, the finding below means a multiple Select value click sends a different field path than the whole-list click, so the modal can bind and save at an array index rather than at the field.
Security: nothing beyond what the scanners cover.
Flow
sequenceDiagram
participant Canvas as Canvas element (SDK)
participant Toolbar as FieldToolbar (SDK)
participant VE as Field edit modal (Visual Editor)
Canvas->>Toolbar: click one Select value, or the whole list
Note over Toolbar: changed here
Toolbar->>Toolbar: isMultipleSelect sets isModalEditable, hides move and delete
Toolbar->>VE: open-field-edit-modal { fieldMetadata }
VE->>VE: form path = instance.fieldPathWithIndex ?? fieldPathWithIndex
VE->>VE: save edited value at that path
Findings: 1 blocker, 0 should fix. The blocker is inline on src/visualBuilder/components/FieldToolbar.tsx.
The guard in handleIndividualFields.ts and the number case in getFieldType.ts both read as scoped correctly. ALLOWED_MODAL_EDITABLE_FIELD has one consumer, so adding SELECT to it changes nothing outside the toolbar, and SELECT is absent from ALLOWED_INLINE_EDITABLE_FIELD, which is what removes inline typing from number dropdowns. The new tests are additive, with no weakened assertions and no skipped cases.
Reviewer candidates: @SahilCs15 authored 12 of the last 30 commits across the changed files, 9 of them on FieldToolbar.tsx, which carries the toolbar change. @srinad007 authored 7, 5 of them on FieldToolbar.tsx.
Not covered: No build, test run, or manual check was done here. The Visual Editor side was read as it stands today, so behaviour once a Select control lands in the modal is not verified. The multiple Select payload has no test in this PR.
Automated review by Claude Code. A human review is still required.
Generated by Claude Code
…elect A value click on a multiple Select opened the modal at the value's index, so the saved value landed inside the array instead of replacing it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0195ab4j6aVrXMYw6Dm6Nndx
🔒 Security Scan Results
⏱️ SLA Breach Summary
✅ BUILD PASSED - All security checks passed |
hitesh-shetty-cstk
left a comment
There was a problem hiding this comment.
Re-review after new commits (pass 2 of 4).
Critical journey: editing and saving an entry field from the canvas. The failure raised on the previous pass, where a multiple Select saved from the modal landed inside the array instead of replacing the list, is fixed by this commit.
Automated review
What this changes: cc16fa6 normalises the open-field-edit-modal payload for a multiple Select. Whichever value was clicked, Edit now sends instance.fieldPathWithIndex set to the field path and multipleFieldMetadata.index set to -1, built as a copy so the original metadata object is left alone. A new test pins the payload for a value click and checks the source object is not mutated.
Business impact: Editing and saving a Select field through the canvas modal. Before this commit, clicking the second value of a multiple Select and saving from the modal wrote the whole-field value at badges.1, so the list was corrupted instead of replaced. The Visual Editor side resolves the modal's form path as instance.fieldPathWithIndex ?? fieldPathWithIndex, so both click targets now land on the field path. I traced that for a top-level Select and for one nested in a modular block, where fieldPathWithIndex keeps the ancestor indices and drops only the value index.
Security: nothing beyond what the scanners cover. Snyk and the repository security workflow are green on this head, and the change adds no new data to the postMessage payload.
Flow
sequenceDiagram
participant E as Editor
participant T as FieldToolbar (SDK, in iframe)
participant M as FieldEditModal (Visual Editor)
E->>T: click one value of a multiple Select
Note over T: changed here
T->>T: isMultipleSelect: instance path to field path, index to -1
T->>M: open-field-edit-modal { fieldMetadata }
M->>M: fieldPath = instance.fieldPathWithIndex ?? fieldPathWithIndex
M->>E: modal bound to the whole field
Findings: 0 blocker, 0 should fix. The blocker from the previous pass is resolved and the incremental diff raised nothing new.
Notes on what I checked, none of them findings. The index overwrite has no effect on the receiving side: OPEN_FIELD_EDIT_MODAL has one subscriber in the Visual Editor and its payload type carries no multipleFieldMetadata, so forcing the index to -1 changes the shape of the message and nothing the modal does with it. For a Select nested in a modular block that index would otherwise hold the parent block's position, which is the case the comment above isWholeMultipleField warns about, but no consumer reads it. The new test is additive, asserts the whole payload rather than a loose matcher, and fails against the previous commit, so it pins the fix rather than accommodating it. vi.clearAllMocks() in the outer afterEach stops the send assertion from matching a call left by an earlier test.
Reviewer candidates: @SahilCs15 authored 9 of the last 30 commits on FieldToolbar.tsx, which carries this change, and 12 across both changed files. @srinad007 authored 5 on FieldToolbar.tsx. No reviewer was requested on this pass, since requests are made only on the opening review. @SahilCs15 owns the toolbar code on the critical path here, so walk them through the payload change before this merges.
Not covered: No build or test run was done here. The Select control is not in the modal yet, so the value shape it reads and writes is still unverified against a Visual Editor build. Only the two changed files were read on this pass. The rest of the pull request was reviewed on pass 1.
Automated review by Claude Code. A human review is still required.
Generated by Claude Code
What changed
The canvas toolbar now treats Select fields (dropdown, radio, checkbox) like the other modal-edited fields, so editors get the Edit button on them.
getFieldTypereturnsselectfor any schema with anenum, including number-typed dropdowns. Before this, number dropdowns were classified as Number and could be typed into inline, which bypassed the choice list.selectis inALLOWED_MODAL_EDITABLE_FIELD, and its icon infieldIconsisEditIcon. Edit sendsopen-field-edit-modalwith the same{ fieldMetadata }payload as Link, Date and URL fields.{ $fieldValue }item into the Select's plain array, which breaks the field.isFieldDisabledalready disables Edit.Release note
The Visual Editor side (the Select control inside the modal) ships separately. Until it is in production, the modal has nothing to show for a Select. Keep this change on
develop_v4and do not release it tostage_v4ormainuntil the Visual Editor side is live in every region.Test evidence
npm cinpm run lintdevelop_v4)npm run test:coverage(what CI runs)npm run buildnpm run prettierdevelop_v4already.FieldToolbar.tsx,fieldToolbar.test.tsxandhandleIndividualFields.tswere unformatted before this change, so they were not reformatted here to keep the diff smallChecks mapped to tests
getFieldTypereturnsselectfor text and number dropdownsgetFieldType.test.ts: "returns select for a number-typed dropdown", "returns select for a text dropdown"open-field-edit-modalwith{ fieldMetadata }(same shape as a Link field:fieldPathWithIndex,instance.fieldPathWithIndex)fieldToolbar.test.tsx, single Select casefieldToolbar.test.tsx, multiple Select instance and whole-field casesisFieldDisabledsays sofieldToolbar.test.tsx, disabled Select casehandleIndividualFields.test.tsNeeds manual QA
Generated by Claude Code