Repository navigation
fix(data-objectstack): read view overrides from the type='view' namespace they are written to (#3774) - #3777
Merged
Conversation
…pace they are written to (#3774) `listViewOverrides` enumerated `GET /api/v1/meta/{objectName}`, putting the object name in the metadata TYPE slot, while `updateViewConfig` persists under `type='view'`. The key spaces are disjoint, so the batch map was empty for every object and every saved list-view personalization (density, column widths, sort, hidden columns, inlineEdit) was written but never read back. Measured before choosing the route: `GET /meta/:type` accepts `?package=` and `?preview=draft` and nothing else, so there is no server-side `?object=` to push the filter into. The read now enumerates `type='view'` once and narrows to the object client-side — the same route `listViews()` already takes over the same rows, now through one shared `viewItemObjectName` accessor so the two readers of that namespace cannot drift. Second half: the batch read no longer swallows failures into `{}`. An empty map is an authoritative "no overrides exist" and still returns early (the batch optimization is intact); a failure now rejects, so the per-view `getView` fallback it had turned into unreachable code is reachable again. `DataSource.listViewOverrides` documents both terms, and `InterfaceListPage` scopes its batch call so a rejection reaches its own per-view fallback. Co-Authored-By: Claude <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub. |
Contributor
✅ Console Performance Budget
📦 Bundle Size Report
Size Limits
|
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.
Fixes #3774
结论:前提成立,两半件都在本 PR
写落在
type='view',读却把对象名塞进了 metadata TYPE 槽,两边键空间不相交;而读方法自吞异常返回{},又让本来正确的逐视图回落变成不可达代码。用户调的密度/列宽/排序/隐藏列/inlineEdit 确实写进了sys_metadata,但永远读不回来。先测量,再定方向(不臆造服务端参数)
单里建议的
/meta/view?object=服务端并不存在。实测两处:packages/client/src/index.ts—meta.getItems(type, options?: { packageId }),URL 只拼?package=。packages/rest/src/rest-server.ts的GET /meta/:typehandler — 只读req.query.package与req.query.preview,再无其它过滤位。所以没有可下推的对象过滤。正确路线就是同文件
listViews()已经在走的那条:枚举一次type='view',在客户端收窄到本对象(它的注释也早写明「metadata index is name-only, not field-typed」)。这不是「拿全量假装过滤」——它就是本仓既有且唯一可行的拼法。顺带把「这行 view 属于哪个对象」抽成 一个 共享 accessor
viewItemObjectName(),listViews与listViewOverrides同源。同一命名空间两个读者各留一份私有判断,迟早漂移成「切换器列得出的视图,表格找不到它的 override」。override 文档的形状按 framework
protocol-view-identity-overlay.test.ts(objectstack#2555)钉的事实取:个性化行的object/name由 overlay 补齐并保留在顶层,与getView读回的是同一份文档——测试里直接断言batched与perView相等,这个相等性才是「一次调用替代 N 次」的前提。第二半件:吞错不再冒充权威
listViewOverrides去掉外层catch { return {} }。两个答案是两件事,不能折叠成同一个值:拒绝不会进缓存(
MetadataCache只在成功时set),所以一次抖动不会把空答案钉住整个 TTL——这条也单独钉了。DataSource.listViewOverrides的接口文档同步写死这两条契约(原文档正是把错误命名空间当成范例写的),让后来的适配器不会再把失败实现成{}。消费半径:两个调用点,不只编辑的那个包
规则改在 data-objectstack,消费者在 app-shell,有两个:
ObjectView.loadBatch—— 它的catch本来就是对的,适配器停止吞错后自然可达,逻辑一字未改;只把三分支读取提取成导出的loadViewOverrides()以便直接钉(沿用本文件defaultListColumnsFromObject的既有先例)。InterfaceListPage—— 这个必须改:它把批量调用放在外层 try 里,适配器改为抛出后,一次失败会连它自己的逐视图getView回落一起跳过。给批量调用加了独立 catch,失败落到逐视图读取。反向验证(先预判方向,再跑)
回退 type 槽修复 → 预判适配器 round-trip 与 wire-route 转红。实测 6 红,报错直接指认旧路由:
注意「空成功返回
{}」那条在此回退下依然绿 —— 错命名空间的枚举同样合法地返回空。这正是空成功测试单独抓不到本 bug、必须写 round-trip 的原因。回退吞错修复 → 这里要如实报告:分诊卡预判的是「(c) 转红」,实测不成立,也不可能成立。(c) 在 app-shell,直接 stub 一个会抛的 dataSource,根本不经过适配器,回退适配器的 catch 动不了它。真正转红的是适配器侧那两条钉:
而 app-shell 8 条全绿。这恰恰说明为什么两半件必须各自带钉:app-shell 那条钉的是「回落分支写对了」,只有适配器那条钉能保证这个分支在真实适配器上够得着。
测试
packages/data-objectstack/src/listViewOverrides.test.ts(9 条,新增)—— round-trip(用适配器自己的写路径灌一个 stubsys_metadata,再用它自己的读路径取;拿手写 fixture 断言会在整个 bug 期间保持绿,因为命名空间错误就住在 fixture 里)、type 槽 + 真实 HTTP 路由双重断言、对象收窄、空成功 vs 失败、拒绝不入缓存。packages/app-shell/src/views/ObjectView.viewOverrides.test.tsx(8 条,新增)—— 批量优先且不再逐视图读、空成功提前返回、失败落到getView、非对象结果落回、无listViewOverrides的适配器不受影响。全量:
data-objectstack + types744 passed / 53 files;app-shell2677 passed(1 skipped)/ 299 files;三包type-check与lint均 0 error。check-control-bytes通过,并对改动文件做了越过该门的手工扫描。Generated by Claude Code