You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Follow-up polish for the record-level inline edit shipped in #2407 (step 0 #2529, P1 #2542, P2 #2549). All items below come out of a live browser verification pass on the showcase app (Project record page, :5180 console against the app-showcase backend): the core flow verified green — shared edit session across highlights + body, ONE atomic PATCH carrying only the edited keys with ifMatch, cancel restores, 409 → ConcurrentUpdateDialog (reload/overwrite), approval-locked save surfaces the server error inline. These are the rough edges found along the way, smallest-cost-first is NOT the order — they're grouped by user impact.
The one real bug found in the same pass — highlight lookup editor gets no reference target because HeaderHighlight only reads reference_to while the backend serves the ObjectStack-convention reference key (details body already normalizes both in DetailSection) — is being fixed separately and is intentionally NOT part of this issue.
1. Pass $expand-ed reference values through to the picker (avoid the extra fetch)
InlineFieldInput collapses an already-expanded reference record to a bare id before handing it to LookupField / UserField:
The record page fetches with populate=account,team_members,…, so data.account often arrives as { id, name, … } — which LookupField.resolveSelectedOption can display directly. Stripping it to an id forces the picker's hydration effect to re-fetch the referenced record via dataSource.findOne just to recover the display name we already had (and leaves the trigger on the placeholder when that fetch can't run). Pass the original value through; keep extractLookupId only for the onChange write-side if needed.
2. Approval-lock preflight: don't let the user type into a locked record
Verified live: saving a budget change triggered flow:showcase_budget_approval, which locks the record — but the page doesn't re-read approval state after refresh(), so the user can re-enter inline edit, fill a draft, and only learns about the lock when Save is rejected (RECORD_LOCKED shown inline; draft preserved — good, but late).
InlineEditSaveBar already has locked / lockedHint props and DetailView has an approval-lock band; the missing piece is the record page re-fetching the approval state after a successful save (and ideally gating enter() / hiding the pencil affordances while locked).
packages/plugin-detail/src/InlineEditSaveBar.tsx (locked prop exists, currently not driven on this path)
app-shell RecordDetailView — wire approval-state refresh into the post-save refresh()
3. Numeric field types fall back to <input type="text">
InlineFieldInput's fallback branch only maps editType === 'number' to a number input:
currency / percent / decimal / integer all get a free-text input — verified live on Project.budget (type currency): arbitrary characters are accepted, no numeric keyboard, no step/min affordance (the field metadata even carries min: 0, unused). Extend the numeric set and consider honoring min/scale.
4. Disable the header "Edit" CTA while an inline edit session is active
While inline editing, the primary 编辑 button in the record header stays enabled; clicking it stacks the classic form-edit surface on top of a live inline draft — two competing edit sessions with no reconciliation. Disable (or hide) it while InlineEditContext.editing is true, mirroring how the save bar owns the session.
5. Keyboard shortcuts for the shared edit session
The session is mouse-only today: Esc only closes open dropdowns, and there's no commit shortcut. Suggest record-level bindings on the provider/save-bar: Esc → cancel (when no popover is open), Cmd/Ctrl+Enter → save. Both should respect saving/locked state.
Verification notes (for whoever picks these up)
Showcase backend on :3000 (framework/examples/app-showcase), console pnpm --filter @object-ui/console dev on :5180, record showcase_project "Website Relaunch".
Existing suites to extend: packages/plugin-detail/src/__tests__/{InlineFieldInput,InlineEditSaveBar,HeaderHighlight.editable,DetailSection.inlineEdit}.test.tsx.
Follow-up polish for the record-level inline edit shipped in #2407 (step 0 #2529, P1 #2542, P2 #2549). All items below come out of a live browser verification pass on the showcase app (Project record page,
:5180console against the app-showcase backend): the core flow verified green — shared edit session across highlights + body, ONE atomic PATCH carrying only the edited keys withifMatch, cancel restores, 409 →ConcurrentUpdateDialog(reload/overwrite), approval-locked save surfaces the server error inline. These are the rough edges found along the way, smallest-cost-first is NOT the order — they're grouped by user impact.1. Pass $expand-ed reference values through to the picker (avoid the extra fetch)
InlineFieldInputcollapses an already-expanded reference record to a bare id before handing it toLookupField/UserField:packages/plugin-detail/src/InlineFieldInput.tsx→value={extractLookupId(value)}The record page fetches with
populate=account,team_members,…, sodata.accountoften arrives as{ id, name, … }— whichLookupField.resolveSelectedOptioncan display directly. Stripping it to an id forces the picker's hydration effect to re-fetch the referenced record viadataSource.findOnejust to recover the display name we already had (and leaves the trigger on the placeholder when that fetch can't run). Pass the original value through; keepextractLookupIdonly for theonChangewrite-side if needed.2. Approval-lock preflight: don't let the user type into a locked record
Verified live: saving a budget change triggered
flow:showcase_budget_approval, which locks the record — but the page doesn't re-read approval state afterrefresh(), so the user can re-enter inline edit, fill a draft, and only learns about the lock when Save is rejected (RECORD_LOCKEDshown inline; draft preserved — good, but late).InlineEditSaveBaralready haslocked/lockedHintprops and DetailView has an approval-lock band; the missing piece is the record page re-fetching the approval state after a successful save (and ideally gatingenter()/ hiding the pencil affordances while locked).packages/plugin-detail/src/InlineEditSaveBar.tsx(lockedprop exists, currently not driven on this path)RecordDetailView— wire approval-state refresh into the post-saverefresh()3. Numeric field types fall back to
<input type="text">InlineFieldInput's fallback branch only mapseditType === 'number'to a number input:packages/plugin-detail/src/InlineFieldInput.tsx→const inputType = editType === 'number' ? 'number' : isDate ? 'date' : 'text';currency/percent/decimal/integerall get a free-text input — verified live on Project.budget (typecurrency): arbitrary characters are accepted, no numeric keyboard, no step/min affordance (the field metadata even carriesmin: 0, unused). Extend the numeric set and consider honoringmin/scale.4. Disable the header "Edit" CTA while an inline edit session is active
While inline editing, the primary 编辑 button in the record header stays enabled; clicking it stacks the classic form-edit surface on top of a live inline draft — two competing edit sessions with no reconciliation. Disable (or hide) it while
InlineEditContext.editingis true, mirroring how the save bar owns the session.5. Keyboard shortcuts for the shared edit session
The session is mouse-only today: Esc only closes open dropdowns, and there's no commit shortcut. Suggest record-level bindings on the provider/save-bar: Esc → cancel (when no popover is open), Cmd/Ctrl+Enter → save. Both should respect
saving/lockedstate.Verification notes (for whoever picks these up)
:3000(framework/examples/app-showcase), consolepnpm --filter @object-ui/console devon:5180, recordshowcase_project"Website Relaunch".showcase_projectconveniently exercises the guardrails:spent_within_budgetcross-field validation (the reason per-field save-on-blur was rejected in Record-level inline edit: editable highlights + one atomic Save (follow-up to #2402) #2407),project_status_flowstate machine, and the budget-approval flow for item 2.packages/plugin-detail/src/__tests__/{InlineFieldInput,InlineEditSaveBar,HeaderHighlight.editable,DetailSection.inlineEdit}.test.tsx.