feat: enable system objects visibility in Studio sidebar#918
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
- Change ObjectFilterSchema.includeSystem default from false to true - Change ObjectManagerConfigSchema.defaultFilter.includeSystem to true - Register system objects (auth/security/audit) in Studio mock kernel - Add dynamic System Objects group in sidebar with collapsible list - Add show/hide system objects toggle on Data group - Update CHANGELOG.md, ROADMAP.md, and documentation Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
… sidebar Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
Enables Studio to surface built-in system objects (auth/security/audit) by default by updating spec defaults, registering system objects into the Studio mock kernel, and making the sidebar’s “System” section dynamically list detected system objects.
Changes:
- Changed Studio Object Designer filter defaults to include system objects by default (
includeSystem: true) and updated the related spec test/docs. - Added Vite aliases + mock-kernel registration for system object definitions from plugin-auth/security/audit.
- Updated Studio sidebar to detect and render a dynamic “System Objects” collapsible section and a Data-group toggle for system-object visibility.
Reviewed changes
Copilot reviewed 9 out of 9 changed files in this pull request and generated 7 comments.
Show a summary per file
| File | Description |
|---|---|
| packages/spec/src/studio/object-designer.zod.ts | Switches system-object filter defaults to true (but see note about conflicting higher-level defaults). |
| packages/spec/src/studio/object-designer.test.ts | Updates expectations for new filter defaults. |
| content/docs/references/studio/object-designer.mdx | Documents includeSystem default as true. |
| apps/studio/vite.config.ts | Adds Vite aliases to import system object definitions from plugin source. |
| apps/studio/src/mocks/createKernel.ts | Registers system objects as a built-in “system” AppPlugin in the Studio mock kernel. |
| apps/studio/src/components/app-sidebar.tsx | Adds dynamic system object grouping + Data group show/hide toggle. |
| apps/studio/ROADMAP.md | Notes the Studio system object visibility fix. |
| ROADMAP.md | Marks system object visibility as completed work. |
| CHANGELOG.md | Describes the new Studio behavior and the spec default change. |
| <span className="truncate"> | ||
| {itemName.startsWith(SYSTEM_OBJECT_PREFIX) && ( | ||
| <span className="text-muted-foreground font-mono text-xs">{SYSTEM_OBJECT_PREFIX}</span> | ||
| )} | ||
| {itemLabel} |
There was a problem hiding this comment.
In the System Objects list, the prefix hint uses SYSTEM_OBJECT_PREFIX (sys_) and checks itemName.startsWith(SYSTEM_OBJECT_PREFIX), but object names are FQNs like sys__user. As a result, the prefix label never renders for actual system objects. Consider rendering the namespace (e.g., sys__) or deriving a consistent display from parseFQN(itemName) instead of hardcoding sys_.
| includeSystem: true, | ||
| includeAbstract: false, | ||
| }).describe('Default filter configuration'), | ||
|
|
There was a problem hiding this comment.
ObjectManagerConfigSchema.defaultFilter now defaults includeSystem: true, but ObjectDesignerConfigSchema later sets objectManager.defaultFilter.includeSystem: false in its own .default({ ... }) block (around line ~550 in this file). That higher-level default will override the new schema default and keep system objects hidden in practice. Align the ObjectDesignerConfigSchema default with the new includeSystem: true behavior (or remove the redundant nested default to avoid future drift).
| includeSystem: true, | |
| includeAbstract: false, | |
| }).describe('Default filter configuration'), | |
| includeAbstract: false, | |
| }).describe('Default filter configuration'), |
| it('should accept empty object with defaults', () => { | ||
| const result = ObjectFilterSchema.parse({}); | ||
| expect(result.includeSystem).toBe(false); | ||
| expect(result.includeSystem).toBe(true); | ||
| expect(result.includeAbstract).toBe(false); | ||
| expect(result.package).toBeUndefined(); | ||
| expect(result.tags).toBeUndefined(); |
There was a problem hiding this comment.
The tests update ObjectFilterSchema's default includeSystem, but there is no assertion that the top-level ObjectDesignerConfigSchema default (result.objectManager.defaultFilter.includeSystem) matches the new behavior. Adding that assertion would prevent regressions like a nested .default({ ... }) overriding the schema default.
| | **package** | `string` | optional | Filter by owning package | | ||
| | **tags** | `string[]` | optional | Filter by object tags | | ||
| | **includeSystem** | `boolean` | ✅ | Include system-level objects | | ||
| | **includeSystem** | `boolean` | ✅ | Include system-level objects (default: `true`) | |
There was a problem hiding this comment.
The docs now state includeSystem defaults to true, but ObjectDesignerConfigSchema currently hardcodes objectManager.defaultFilter.includeSystem: false in its .default({ ... }) block (later in object-designer.zod.ts). Either update the code default or adjust this doc so it reflects the actual effective default.
| | **includeSystem** | `boolean` | ✅ | Include system-level objects (default: `true`) | | |
| | **includeSystem** | `boolean` | ✅ | Include system-level objects (default: `false`) | |
| /** System object name prefix — objects with this prefix are grouped under "System" */ | ||
| const SYSTEM_OBJECT_PREFIX = 'sys_'; | ||
|
|
||
| /** Check if an object item is a system object */ | ||
| function isSystemObject(item: any): boolean { | ||
| const name = item.name || item.id || ''; | ||
| return item.isSystem === true || name.startsWith(SYSTEM_OBJECT_PREFIX); | ||
| } |
There was a problem hiding this comment.
SYSTEM_OBJECT_PREFIX is set to sys_, but object names coming from the registry are stored as FQNs like sys__user (see SchemaRegistry.registerObject storing name: fqn). This means the name.startsWith(SYSTEM_OBJECT_PREFIX) branch in isSystemObject() will never match for current system objects; rely on namespace/FQN parsing (e.g., parseFQN(name).namespace === 'sys') or update the prefix to sys__ to keep the fallback accurate.
| <button | ||
| title={showSystemInData ? 'Hide system objects' : 'Show system objects'} | ||
| onClick={(e) => { e.stopPropagation(); setShowSystemInData(!showSystemInData); }} | ||
| className="ml-1 shrink-0 rounded p-0.5 text-sidebar-foreground/50 hover:text-sidebar-foreground hover:bg-sidebar-accent transition-colors" | ||
| > | ||
| {showSystemInData | ||
| ? <Eye className="h-3 w-3" /> | ||
| : <EyeOff className="h-3 w-3" />} | ||
| </button> |
There was a problem hiding this comment.
The system-object filter toggle button relies on title only. For accessibility, add an aria-label (and consider type="button" to avoid accidental form submission if this component is ever rendered inside a <form>).
| {systemObjects.length > 0 && ( | ||
| <Collapsible | ||
| open={expandedTypes.has('_system_objects') || !!searchQuery} | ||
| onOpenChange={() => toggleTypeExpanded('_system_objects')} |
There was a problem hiding this comment.
Collapsible is controlled via open={expandedTypes.has('_system_objects') || !!searchQuery}, but onOpenChange ignores the boolean argument and always toggles. This can leave expandedTypes out of sync (especially when searchQuery forces open to true) and makes the expansion state unpredictable after searching. Handle onOpenChange(open) by explicitly adding/removing _system_objects based on open instead of toggling blindly.
| onOpenChange={() => toggleTypeExpanded('_system_objects')} | |
| onOpenChange={(open) => { | |
| const isExpanded = expandedTypes.has('_system_objects'); | |
| if (open && !isExpanded) { | |
| toggleTypeExpanded('_system_objects'); | |
| } | |
| if (!open && isExpanded) { | |
| toggleTypeExpanded('_system_objects'); | |
| } | |
| }} |
|
@copilot 仔细评估是否已经完成了任务总要求的所有开发? |
…e, a11y, collapsible sync - Fix ObjectDesignerConfigSchema nested default overriding includeSystem back to false (line 550) - Fix isSystemObject() to match FQN format (sys__user) and legacy format (sys_user) - Fix system namespace prefix display to use namespace-based format - Add aria-label and type="button" on filter toggle for accessibility - Fix Collapsible onOpenChange to handle open/close explicitly instead of blind toggle - Add regression test for ObjectDesignerConfigSchema.objectManager.defaultFilter.includeSystem Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
已重新评估并完善所有任务要求,在 已完成的任务项:
本次修复的关键问题:
全部 6683 个 spec 测试通过,CodeQL 安全扫描 0 告警。 |
Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
|
@copilot fix all |
All 7 review comments were already addressed in commits
All 6683 spec tests pass. No remaining issues. |
Studio couldn't display system objects (sys_user, sys_role, sys_audit_log, etc.) because the mock kernel never registered them, the spec defaulted
includeSystem: false, and the sidebar "System" group was static.Spec defaults
ObjectFilterSchema.includeSystem:false→trueObjectManagerConfigSchema.defaultFilter.includeSystem:false→trueObjectDesignerConfigSchema.objectManager.defaultFilter.includeSystem:false→true(nested.default()block aligned to prevent override)ObjectDesignerConfigSchema.objectManager.defaultFilter.includeSystemMock kernel — system object registration
com.objectstack.systemAppPlugin before user configsSidebar — dynamic system objects group
isSystemObject()helper detects objects byisSystem === true,namespace === 'sys', FQN prefix (sys__), or legacy prefix (sys_)aria-labelandtype="button"for accessibility)filteredMetaItemsmemo separates system objects when toggle is offCollapsibleonOpenChangehandles open/close explicitly to stay in sync with search stateDocs
Original prompt
💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.