Skip to content

refactor: migrate system settings pages to ObjectView metadata-driven rendering#1139

Merged
hotlong merged 3 commits intomainfrom
copilot/refactor-system-settings-page
Mar 30, 2026
Merged

refactor: migrate system settings pages to ObjectView metadata-driven rendering#1139
hotlong merged 3 commits intomainfrom
copilot/refactor-system-settings-page

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Mar 30, 2026

System settings pages (Users, Orgs, Roles, Permissions, Audit Log) used hand-written HTML tables with manual fetch/CRUD logic, duplicating ~500 lines of nearly identical code across 5 files. Replaced with the platform's ObjectView from @object-ui/plugin-view, driven by existing systemObjects.ts metadata.

Changes

  • New SystemObjectViewPage component — shared wrapper that builds an ObjectViewSchema from systemObjects.ts definitions and renders ObjectView with the adapter dataSource
  • All 5 management pages now delegate to SystemObjectViewPage (~25 lines each, down from ~140)
    • CRUD gated by isAdmin via operations config
    • Audit log uses readOnly mode
    • Search, sort, filter, pagination come free from ObjectView
  • Tests updated — mock @object-ui/plugin-view and assert schema props (objectName, operations, columns) rather than testing hand-rolled table rendering
// Before: 144 lines of useState, useCallback, fetch, hand-written <table>
// After:
export function UserManagementPage() {
  const { user } = useAuth();
  return (
    <SystemObjectViewPage
      objectName="sys_user"
      title="User Management"
      description="Manage system users and their roles"
      icon={Users}
      isAdmin={user?.role === 'admin'}
    />
  );
}

22 system page tests pass, 750 total console tests pass. CHANGELOG.md and ROADMAP.md updated.


💡 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.

@vercel
Copy link
Copy Markdown

vercel bot commented Mar 30, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
objectui-demo Ready Ready Preview, Comment Mar 30, 2026 4:17am
2 Skipped Deployments
Project Deployment Actions Updated (UTC)
objectui Ignored Ignored Mar 30, 2026 4:17am
objectui-storybook Ignored Ignored Mar 30, 2026 4:17am

Request Review

… rendering

Replace hand-written HTML tables in all 5 system management pages
(Users, Organizations, Roles, Permissions, Audit Log) with the
ObjectView component from @object-ui/plugin-view.

- Create shared SystemObjectViewPage component
- Each page driven by systemObjects.ts metadata definitions
- Automatic search, sort, filter, and CRUD from ObjectView
- Admin-only CRUD controlled via ObjectView operations config
- Audit log uses read-only mode (all mutations disabled)
- Update 22 tests to validate new ObjectView integration
- Update CHANGELOG.md and ROADMAP.md

Agent-Logs-Url: https://github.com/objectstack-ai/objectui/sessions/5059a194-c7d8-47c0-a6d8-cafa43dea3e2

Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
Copilot AI changed the title [WIP] Refactor system settings pages to use standard ObjectView refactor: migrate system settings pages to ObjectView metadata-driven rendering Mar 30, 2026
Copilot AI requested a review from hotlong March 30, 2026 04:19
@hotlong
Copy link
Copy Markdown
Contributor

hotlong commented Mar 30, 2026

@copilot 是否建议统一到系统标准路由,包括列表表页和记录详情页

Copy link
Copy Markdown
Contributor Author

Copilot AI commented Mar 30, 2026

@copilot 是否建议统一到系统标准路由,包括列表表页和记录详情页

是的,建议作为下一步增强。当前 PR 已将列表页统一到 ObjectView,接下来可以:

  1. 添加详情页路由 — 为每个系统对象添加 /system/users/:recordId 类似的路由,复用 RecordDetailView
  2. 配置 ObjectView navigation — 在 SystemObjectViewPage 的 schema 中设置 navigation: { mode: 'drawer' }mode: 'page',使行点击能打开详情
  3. 统一路由结构 — 将 SystemRoutes 中的扁平路由改为嵌套路由:
<Route path="users" element={<UserManagementPage />} />
<Route path="users/:recordId" element={<SystemRecordDetailPage objectName="sys_user" />} />

这些改动超出当前 PR 的范围(本 PR 聚焦于列表页从手写表格迁移到 ObjectView),建议作为单独的 issue/PR 跟进。

@hotlong
Copy link
Copy Markdown
Contributor

hotlong commented Mar 30, 2026

@copilot 我的意思是每一个系统表就是一个标准的对象,如果把系统设置也定义为一个应用,那岂不是直接可以使用现有的系统路由,根本不用自己开发页面。

Copy link
Copy Markdown
Contributor Author

Copilot AI commented Mar 30, 2026

@copilot 我的意思是每一个系统表就是一个标准的对象,如果把系统设置也定义为一个应用,那岂不是直接可以使用现有的系统路由,根本不用自己开发��...

理解了,这个方向是完全可行的。当前 adapter 对 sys_ 对象没有任何特殊处理,dataSource.find('sys_user')dataSource.find('contact') 走的是同一条 ObjectQL 路径。

如果将系统对象注册为标准应用(例如 system_admin app),确实可以零页面代码直接复用现有的 /:objectName/:objectName/record/:recordId 路由,包括列表、详情、CRUD、搜索过滤等全部能力。

实现需要:

  1. objectstack.config.ts 中用 defineStack() 注册系统对象 + 创建 system_admin 应用定义
  2. MetadataProvider 或 config 中注入该 app,使其出现在 app 列表中
  3. 处理权限控制 — 只有 admin 角色可见/可操作
  4. 决定路由归属 — 是放到 /apps/system_admin/* 还是保留 /system/* 作为别名

这个改动涉及 config 层 + metadata 层 + 路由层的联动,超出本 PR 范围。建议作为独立 issue 跟进,本 PR 的 SystemObjectViewPage 可作为过渡方案。

@hotlong hotlong marked this pull request as ready for review March 30, 2026 05:48
Copilot AI review requested due to automatic review settings March 30, 2026 05:48
@hotlong hotlong merged commit f7733b1 into main Mar 30, 2026
6 checks passed
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Refactors the console’s system settings management pages to use the metadata-driven ObjectView (@object-ui/plugin-view) instead of hand-built tables and bespoke CRUD/fetch logic, leveraging systemObjects.ts as the source of truth.

Changes:

  • Added a shared SystemObjectViewPage wrapper that builds an ObjectViewSchema from systemObjects.ts and renders ObjectView with the adapter dataSource.
  • Migrated Users/Orgs/Roles/Permissions/Audit Log pages to delegate rendering + CRUD gating to SystemObjectViewPage.
  • Updated system page tests to mock ObjectView and assert schema configuration; updated ROADMAP/CHANGELOG accordingly.

Reviewed changes

Copilot reviewed 9 out of 9 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
apps/console/src/pages/system/SystemObjectViewPage.tsx New shared wrapper that maps systemObjects.ts metadata into an ObjectViewSchema and renders ObjectView.
apps/console/src/pages/system/UserManagementPage.tsx Simplified to delegate to SystemObjectViewPage for sys_user.
apps/console/src/pages/system/OrgManagementPage.tsx Simplified to delegate to SystemObjectViewPage for sys_org.
apps/console/src/pages/system/RoleManagementPage.tsx Simplified to delegate to SystemObjectViewPage for sys_role.
apps/console/src/pages/system/PermissionManagementPage.tsx Simplified to delegate to SystemObjectViewPage for sys_permission.
apps/console/src/pages/system/AuditLogPage.tsx Simplified to delegate to SystemObjectViewPage for sys_audit_log in read-only mode.
apps/console/src/tests/SystemPages.test.tsx Tests updated to mock @object-ui/plugin-view and assert ObjectView schema + dataSource wiring.
ROADMAP.md Documents completion of “ObjectView-Driven System Pages”.
CHANGELOG.md Notes the system pages refactor to ObjectView.

</div>
</div>

{dataSource && (
Copy link

Copilot AI Mar 30, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ObjectView is not rendered while dataSource is null. Since AdapterProvider initializes the adapter asynchronously, this can leave the page showing only the header (no loading/empty/error state) during initial load or reconnects. Consider rendering a loading indicator or a fallback message when dataSource is null (and/or disabling the page until the adapter is ready).

Suggested change
{dataSource && (
{!dataSource ? (
<div
className="flex items-center justify-center py-10 text-sm text-muted-foreground"
data-testid={`system-page-${objectName}-loading`}
>
Preparing data connection. Please wait...
</div>
) : (

Copilot uses AI. Check for mistakes.
Comment on lines +54 to +66
const viewDef = objDef.views?.[0];
const canMutate = !readOnly && isAdmin;

const schema: ObjectViewSchema = {
type: 'object-view',
objectName,
showSearch: true,
showFilters: true,
showSort: true,
showCreate: canMutate,
table: {
columns: viewDef?.columns,
},
Copy link

Copilot AI Mar 30, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The previous AuditLog page explicitly fetched with $orderby: { createdAt: 'desc' } (newest-first). The new schema does not set any default sort, so audit entries may render in an arbitrary/oldest-first order depending on backend defaults. Add a default sort for audit logs (e.g., via schema.table.defaultSort / view metadata) so the audit log remains chronological by default.

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

系统设置各子页面改造建议:统一采用标准 ObjectView 表格和表单驱动

3 participants