feat(releases): deep-link release validation errors to the offending field#12978
feat(releases): deep-link release validation errors to the offending field#12978EoinFalconer wants to merge 2 commits into
Conversation
…field The validation error indicator in the release detail document table was a static icon (with only an error-count tooltip), so editors were told a document had errors but had no easy way to find which field. It is now a link that opens the document in the release perspective and focuses the first field-level validation error, reusing the existing params.path field-focus mechanism. - Extract ReleaseDocumentPreview's intent/perspective derivation into a shared getReleaseDocumentIntent() helper so the validation link resolves to the same document/perspective, with an optional focus path. - Make the validation column icon an IntentLink carrying path = first error path. - Preserve the path param in getIntentState's edit fast-path so the deep-link works even when the target document pane is already open. Fixes SAPP-3892. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
✅ E2E Tests🟢 203 passed • 🟡 3 flaky • (⚪ 90 skipped) • view full report • view run |
📦 Bundle Stats —
|
| Metric | Value | vs main (604e337) | vs v5.30.0 |
|---|---|---|---|
| Internal (raw) | 4.55 MB | +309 B, +0.0% | +1.8 KB, +0.0% |
| Internal (gzip) | 1.05 MB | +90 B, +0.0% | +768 B, +0.1% |
| Bundled (raw) | 12.33 MB | +313 B, +0.0% | -4.7 KB, -0.0% |
| Bundled (gzip) | 2.77 MB | +85 B, +0.0% | -761 B, -0.0% |
| Import time | 1.55s | -20ms, -1.3% | +56ms, +3.8% |
bin:sanity
| Metric | Value | vs main (604e337) | vs v5.30.0 |
|---|---|---|---|
| Internal (raw) | 7.1 KB | - | - |
| Internal (gzip) | 2.9 KB | - | - |
| Bundled (raw) | 7.1 KB | - | - |
| Bundled (gzip) | 2.8 KB | - | - |
| Import time | 5ms | -0ms, -0.9% | +0ms, +7.2% |
🗺️ View treemap · Artifacts
Details
- Import time regressions over 10% are flagged with
⚠️ - Sizes shown as raw / gzip 🗜️. Internal bytes = own code only. Total bytes = with all dependencies. Import time = Node.js cold-start median.
📚 TypeDoc Generation Result✅ TypeDoc generated successfully!
The TypeDoc JSON file has been generated and validated. All documentation scripts completed successfully. |
⚡️ Editor Performance ReportUpdated Tue, 09 Jun 2026 08:44:01 GMT
Detailed information🏠 Reference resultThe performance result of
🧪 Experiment resultThe performance result of this branch
📚 Glossary
|
There was a problem hiding this comment.
Pull request overview
This PR improves the Releases tool UX by turning the release validation error indicator into a deep-link that opens the affected document (in the correct release/perspective context) and focuses the first field-level validation error via the existing params.path mechanism.
Changes:
- Add shared
getReleaseDocumentIntent()helper to centralize release-aware intent params/searchParams (optionally including a focuspath). - Make the validation error icon in the release document table an
IntentLinkthat passespathto focus the first field-level error. - Update Structure tool intent fast-path (
getIntentState) to preservepath, with unit tests covering the behavior.
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| packages/sanity/src/structure/getIntentState.ts | Preserves path in the open-pane edit intent fast-path. |
| packages/sanity/src/structure/getIntentState.test.ts | Adds unit tests verifying path is preserved through the fast-path. |
| packages/sanity/src/core/releases/tool/detail/documentTable/DocumentTableColumnDefs.tsx | Turns validation icon into a deep-link IntentLink with focused error path + accessible label. |
| packages/sanity/src/core/releases/tool/components/ReleaseDocumentPreview.tsx | Refactors preview link intent construction to use the shared helper. |
| packages/sanity/src/core/releases/tool/components/getReleaseDocumentIntent.ts | New helper for consistent release-aware intent params/searchParams (and optional focus path). |
| packages/sanity/src/core/releases/tool/components/getReleaseDocumentIntent.test.ts | Adds unit tests covering helper behavior across release states and optional path. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| case 'edit': | ||
| return {inspect, comment, task, scheduledDraft} | ||
| // `path` deep-links to (and focuses) a specific field when the document opens. | ||
| return {inspect, comment, task, scheduledDraft, path} | ||
| default: | ||
| return EMPTY_PARAMS |
There was a problem hiding this comment.
Good catch — fixed in d7696e2. The edit fast-path now forwards rev/since/historyEvent/historyVersion/archivedRelease (plus path) to match the cold-path resolver, so opening a release/history version works the same whether or not the pane is already open.
Coverage Report
File Coverage
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||
…path Address review feedback: getIntentState's open-pane fast-path forwarded only a hardcoded subset of edit-intent params, dropping rev/since/historyEvent/ historyVersion/archivedRelease that the cold-path resolver (resolveIntent) forwards. This could open a release/history version at the wrong view when the target document pane was already open. Forward them too. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
| comment?: string | ||
| task?: string | ||
| scheduledDraft?: string | ||
| path?: string |
There was a problem hiding this comment.
There are two intent resolvers that must agree: this getIntentState fast-path (used when a pane is already open, to avoid resetting panes) and the resolveIntent cold path (resolveIntent.ts:144). The cold path forwards all params via rest-spread (otherParams = {...params} minus id/type); this fast-path forwards a hardcoded allowlist. That mismatch is the root cause of the bug — path existed in the params but the allowlist didn't list it, so the already-open-pane case dropped it.
Widening the allowlist from 4 to 11 entries fixes path today, but the next edit-intent param added anywhere will silently break the same way (version, for instance, is forwarded for create but not edit — whether that's intentional or not, the allowlist gives you no signal). Closing the gap structurally avoids the recurrence:
case 'edit': {
const {id, type, template, ...rest} = params
return rest
}
jordanl17
left a comment
There was a problem hiding this comment.
Nice - just one comment to maintain consistency between getIntentState with the existing resolveIntent
Description
Editors are told a document in a content release has validation errors, but the release detail view's validation indicator was a static icon (with only an error-count tooltip) — there was no way to find which field. This makes the indicator a link that opens the document in the release perspective and focuses the first field-level validation error. Fixes SAPP-3892.
It reuses the existing
params.pathfield-focus mechanism (already used by the in-document validation inspector and the incoming-references deep links) — the release validation data already carries the marker paths, so this is mostly UI wiring.What to review
getReleaseDocumentIntent.ts(new) — extractsReleaseDocumentPreview's intent/perspective derivation (active / published / archived / cardinality-one) into a shared helper, with an optional focuspath.ReleaseDocumentPreviewnow uses it (single source of truth → the validation link resolves to the exact same document + perspective as the title link).DocumentTableColumnDefs.tsx— the validation column icon is now anIntentLinkcarryingpath= the first field-level error's path (falls back to the first error). Existing count tooltip retained;aria-labeladded.getIntentState.ts— preserve thepathparam in theeditfast-path (the already-open-pane case), matchingresolveIntent's cold path which already forwards it.Testing
getReleaseDocumentIntent(6 cases — params + perspective search params for active/published/archived/cardinality-one, plus path inclusion/omission);getIntentState(path preserved through the open-pane fast-path — fails without the fix).pnpm --filter sanity check:typesclean; releases tool tests pass (theReleaseTypePickerscheduled-time test is a pre-existing flake — passed on isolated re-run).Notes for release
Clicking the validation error icon for a document in a content release now opens the document and jumps to the offending field, instead of only showing an error count.