Repository navigation
fix(app-shell): the notify recipients editor writes and keeps { emailField } - #25996
Conversation
…Field }
A stored `recipients: { emailField }` read as no recipients, so the first
edit replaced it. The editor now reads it as one Email field row and writes
it back as read, offers an Email field row that suggests only email-typed
fields of the trigger object and stores the whole value, and writes
`channels: ['email']` in the same patch when the node does not already name
email alone. On a node that sends email the Record field row no longer
suggests an email-typed field, and a stored one says the address must be a
user's.
Claude-Session: https://claude.ai/code/session_01VrsYtPiyNCyFG3fUsVvNEQ
Co-authored-by: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VrsYtPiyNCyFG3fUsVvNEQ Co-authored-by: Claude <noreply@anthropic.com>
席位核对 · ACCEPT · seat
|
⛔ merge queue 构建失败 — 先分诊,再决定要不要重排队列构建 40293762961 红了。队列跑的是全量套件(PR 侧 CI 只跑 affected 子集), 分类: 失败的 job(日志抽取,best effort):
跨 PR 相同签名(24h,按失败测试文件聚合):
历史信号:
分诊清单:
Generated by Claude Code · merge-queue-triage workflow (#4859) |
|
Seat |
Requested by Steve · project thread
Fixes #25900
Clause-②: no
Metadata-protocol: none
What changes
The Studio notify node's recipients editor (
FlowRecipientsField) now knows the spec's fourth recipient form, the email-field recipient{ emailField: 'FIELD' }(NotifyEmailFieldRecipientSchema, the wholerecipientsvalue, on a node whose only channel isemail).recipients: { emailField }read as no recipients (readRecipientskept only strings and CEL envelopes), so the first edit of the node replaced it. It now reads as one Email field row, and an unedited row is written back as the object it was read from.email-typed field of the trigger object (the suggestions are filtered by field type) and stores{ emailField: 'FIELD' }as the whole value. It is offered in the type select only while it is the sole row, and "Add recipient" is disabled beside it, so the editor never writes it as a list entry (which the spec refuses).channels: ['email']when the node does not already nameemailalone (either spelling, string or list, counts). A blur that changes nothing writes no channel. A stored{ emailField }on a node naming other channels shows a note and a one-click "Send by email only" fix.channelsincludeemail, the Record field picker no longer suggestsemail-typed fields: the runtime refuses the address that row'srecord.FIELDenvelope evaluates to unless a user holds it (service-automation notify node,screenComputedAddresses). A stored Record field row over such a field keeps its value and says the address must belong to a user.Where the fix lives, and one file beyond the card's list
FlowRecipientsField.tsx— the row kind, read/write, notes.FlowReferenceField.tsx—ResolvedRefgains optionalonlyFieldTypes/exceptFieldTypesfor theobject-fieldkind;resolveObjectNameis exported so the recipients field reads the trigger object's field types.FlowNodeConfigField.tsx—onCommittakes an optionalalongsidemap of sibling keys and the recipients case forwards it.FlowNodeInspector.tsx(declared to the seat as a file-surface addition) —setFieldappliesalongsideto the same node before the one patch. The write is the inspector's: two sequentialsetFieldcalls each start from the node the render closed over, so the second would drop the first key.i18n.ts— en and zh strings for the new type, placeholder and notes.Tests
New file
FlowRecipientsField.emailField-25900.test.tsx, 11 tests: stored{ emailField }round-trip and its row, Add disabled beside it, the Email field picker's suggestions and its commit (accepted by the installedNotifyConfigSchema, withchannels), no channel write when the node already names email alone, not offered beside another row, the stored-wrong-channels note and fix, a non-email field named, the Record field filter on email and non-email nodes, and the inspector writingrecipientsandchannelsin exactly one patch.expected [] to deeply equal [ { kind: 'emailField', … } ]andexpected null not to be null.e25d3a6e:FlowRecipientsField*2 files, 28/28 passed; the wholemetadata-admin/directory 597 files, 6561 passed, 1 skipped.scripts/ablation-replace.mjs, mutation landedanchor 1 -> 0, restoredblob == HEAD,git diff HEADempty): dropping the email-field arm from thereadRecipientsfilter turns exactly the 5 stored-value tests red (11 → 6 passed), the write and filter tests stay green.pnpm --filter @object-ui/app-shell run type-check: exit 0 (the test program lists the new test file).Gates
node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstackate25d3a6ederived 34 commands; all 34 exit 0, and--ranreconciles 34 derived, 34 run, 0 NOT-MEASURED (a derived zero, each line carrying its exit code).check:type-check-debtfirst returned queue-timeout (exit 3, nothing measured) and was re-run under the lock: OK. Type Check UI, Lint UI and Build & E2E UI are CI's.Acceptance notes
stringListeditor, which reads a storedchannels: 'email'string as an empty list; an edit there then writes a list withoutemail. This PR writeschannelsas a list so the field shows it; a stored string spelling stays affected. Reported to the seat for filing.react-refresh/only-export-componentswarnings come from the new helper exports (isEmailFieldRecipient,readChannels,isEmailOnlyChannels,resolveObjectName), the same pattern as the helpers these files already export.{ emailField }entry (which the spec refuses) is now kept as read instead of dropped; the spec's refusal names it.Session:
https://claude.ai/code/session_01VrsYtPiyNCyFG3fUsVvNEQGenerated by Claude Code