Skip to content

Commit 7eb142a

Browse files
authored
Merge pull request #1196 from objectstack-ai/copilot/merge-objectmanagerpage-into-metadata
2 parents ab0ccf2 + ebc6fd4 commit 7eb142a

13 files changed

+617
-584
lines changed

CHANGELOG.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,20 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
## [Unreleased]
99

10+
### Changed
11+
12+
- **Merged ObjectManagerPage into MetadataManagerPage pipeline** (`@object-ui/console`): Removed the standalone `ObjectManagerPage` component. Object management is now fully handled by the generic `MetadataManagerPage` (list view) and `MetadataDetailPage` (detail view) pipeline. The object type config in `metadataTypeRegistry` uses `listComponent: ObjectManagerListAdapter` for the custom list UI and `pageSchemaFactory: buildObjectDetailPageSchema` for the detail page, eliminating redundant page code and centralizing all metadata management through a single architecture.
13+
14+
- **`listComponent` extension point on MetadataTypeConfig** (`@object-ui/console`): New optional `listComponent` field allows metadata types to inject a fully custom list component into `MetadataManagerPage`, replacing the default card/grid rendering. The page shell (header, back button, title) is still rendered by the generic manager. `MetadataListComponentProps` interface provides `config`, `basePath`, `metadataType`, and `isAdmin` to the custom component.
15+
16+
- **Routes unified to `/system/metadata/object`** (`@object-ui/console`): All entry points (sidebar, QuickActions, SystemHubPage hub cards) now point to `/system/metadata/object` instead of `/system/objects`. Legacy `/system/objects` routes redirect to the new path for backward compatibility.
17+
18+
### Removed
19+
20+
- **`ObjectManagerPage`** (`@object-ui/console`): Deleted `pages/system/ObjectManagerPage.tsx`. All object management functionality is now delivered through the `ObjectManagerListAdapter` + `MetadataManagerPage`/`MetadataDetailPage` pipeline.
21+
22+
- **`customRoute` on object type config** (`@object-ui/console`): The object metadata type no longer uses `customRoute: '/system/objects'`. It now routes through the standard metadata pipeline at `/system/metadata/object`.
23+
1024
### Fixed
1125

1226
- **Protocol bridges** (`@object-ui/core`): Updated `DndProtocol`, `KeyboardProtocol`, and `NotificationProtocol` to align with `@objectstack/spec` v4 type changes where `ariaLabel`, `label`, `title`, and `message` fields are now plain strings instead of i18n translation objects (`{ key, defaultValue }`).

ROADMAP.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -943,8 +943,11 @@ Enterprise-grade visual designers for managing object definitions and configurin
943943
- [x] `boolean` field type — renders Shadcn Switch toggle with Yes/No label
944944

945945
**MetadataDetailPage & Provider Enhancements:**
946-
- [x] Auto-redirect for custom page types (object → `/system/objects/:name`)
946+
- [x] Auto-redirect for custom page types (object → `/system/objects/:name`) — removed; object now uses metadata pipeline
947947
- [x] `getItemsByType(type)` method on MetadataProvider for dynamic registry access
948+
- [x] Object type merged into MetadataManagerPage pipeline — `ObjectManagerPage` removed, replaced by `ObjectManagerListAdapter` via `listComponent` extension point
949+
- [x] `listComponent` extension point on MetadataTypeConfig for injecting custom list UIs
950+
- [x] All entry points (sidebar, QuickActions, hub cards) unified to `/system/metadata/object`
948951

949952
**Technical Debt Cleanup:**
950953
- [x] Unified icon resolver — consolidated 3 duplicated ICON_MAP/resolveIcon into shared `getIcon` utility

apps/console/src/App.tsx

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { BrowserRouter, Routes, Route, Navigate, useNavigate, useLocation } from 'react-router-dom';
1+
import { BrowserRouter, Routes, Route, Navigate, useNavigate, useLocation, useParams } from 'react-router-dom';
22
import { useState, useEffect, useCallback, lazy, Suspense, useMemo, type ReactNode } from 'react';
33
import { ModalForm } from '@object-ui/plugin-form';
44
import { Empty, EmptyTitle, EmptyDescription, Button } from '@object-ui/components';
@@ -47,7 +47,6 @@ const ForgotPasswordPage = lazy(() => import('./pages/ForgotPasswordPage').then(
4747
// System Admin Pages (lazy — rarely accessed)
4848
const SystemHubPage = lazy(() => import('./pages/system/SystemHubPage').then(m => ({ default: m.SystemHubPage })));
4949
const AppManagementPage = lazy(() => import('./pages/system/AppManagementPage').then(m => ({ default: m.AppManagementPage })));
50-
const ObjectManagerPage = lazy(() => import('./pages/system/ObjectManagerPage').then(m => ({ default: m.ObjectManagerPage })));
5150
const MetadataManagerPage = lazy(() => import('./pages/system/MetadataManagerPage').then(m => ({ default: m.MetadataManagerPage })));
5251
const MetadataDetailPage = lazy(() => import('./pages/system/MetadataDetailPage').then(m => ({ default: m.MetadataDetailPage })));
5352
const UserManagementPage = lazy(() => import('./pages/system/UserManagementPage').then(m => ({ default: m.UserManagementPage })));
@@ -61,7 +60,6 @@ const ProfilePage = lazy(() => import('./pages/system/ProfilePage').then(m => ({
6160
const HomePage = lazy(() => import('./pages/home/HomePage').then(m => ({ default: m.HomePage })));
6261
const HomeLayout = lazy(() => import('./pages/home/HomeLayout').then(m => ({ default: m.HomeLayout })));
6362

64-
import { useParams } from 'react-router-dom';
6563
import { ThemeProvider } from './components/theme-provider';
6664
import { ConsoleToaster } from './components/ConsoleToaster';
6765

@@ -294,8 +292,8 @@ export function AppContent() {
294292
<Route path="create-app" element={<CreateAppPage />} />
295293
<Route path="system" element={<SystemHubPage />} />
296294
<Route path="system/apps" element={<AppManagementPage />} />
297-
<Route path="system/objects" element={<ObjectManagerPage />} />
298-
<Route path="system/objects/:objectName" element={<ObjectManagerPage />} />
295+
<Route path="system/objects" element={<Navigate to="/system/metadata/object" replace />} />
296+
<Route path="system/objects/:objectName" element={<ObjectRedirect />} />
299297
<Route path="system/users" element={<UserManagementPage />} />
300298
<Route path="system/organizations" element={<OrgManagementPage />} />
301299
<Route path="system/roles" element={<RoleManagementPage />} />
@@ -390,8 +388,8 @@ export function AppContent() {
390388
{/* System Administration Routes */}
391389
<Route path="system" element={<SystemHubPage />} />
392390
<Route path="system/apps" element={<AppManagementPage />} />
393-
<Route path="system/objects" element={<ObjectManagerPage />} />
394-
<Route path="system/objects/:objectName" element={<ObjectManagerPage />} />
391+
<Route path="system/objects" element={<Navigate to="/system/metadata/object" replace />} />
392+
<Route path="system/objects/:objectName" element={<ObjectRedirect />} />
395393
<Route path="system/users" element={<UserManagementPage />} />
396394
<Route path="system/organizations" element={<OrgManagementPage />} />
397395
<Route path="system/roles" element={<RoleManagementPage />} />
@@ -476,6 +474,19 @@ function RootRedirect() {
476474
return <Navigate to="/home" replace />;
477475
}
478476

477+
/**
478+
* Redirect helper for legacy `/system/objects/:objectName` routes.
479+
* Preserves the `objectName` URL param so that
480+
* `/system/objects/account` → `/system/metadata/object/account`.
481+
*/
482+
function ObjectRedirect() {
483+
const { objectName } = useParams<{ objectName?: string }>();
484+
const target = objectName
485+
? `/system/metadata/object/${objectName}`
486+
: '/system/metadata/object';
487+
return <Navigate to={target} replace />;
488+
}
489+
479490
/**
480491
* SystemRoutes — Top-level system admin routes accessible without any app context.
481492
* Provides a minimal layout with system navigation sidebar.
@@ -486,8 +497,8 @@ function SystemRoutes() {
486497
<Routes>
487498
<Route path="/" element={<SystemHubPage />} />
488499
<Route path="apps" element={<AppManagementPage />} />
489-
<Route path="objects" element={<ObjectManagerPage />} />
490-
<Route path="objects/:objectName" element={<ObjectManagerPage />} />
500+
<Route path="objects" element={<Navigate to="/system/metadata/object" replace />} />
501+
<Route path="objects/:objectName" element={<ObjectRedirect />} />
491502
<Route path="users" element={<UserManagementPage />} />
492503
<Route path="organizations" element={<OrgManagementPage />} />
493504
<Route path="roles" element={<RoleManagementPage />} />

apps/console/src/__tests__/MetadataDetailPage.test.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -247,7 +247,7 @@ describe('MetadataDetailPage', () => {
247247
</MemoryRouter>,
248248
);
249249
fireEvent.click(screen.getByTestId('back-to-list-btn'));
250-
expect(mockNavigate).toHaveBeenCalledWith('/system/objects');
250+
expect(mockNavigate).toHaveBeenCalledWith('/system/metadata/object');
251251
});
252252
});
253253
});

0 commit comments

Comments
 (0)