Skip to content

Commit 67103cc

Browse files
feat(setup): Setup's metadata pages open Studio's All metadata area; the catalog's Active switch moves to each item's page (#28818)
<!-- claude-projects-attribution: {"github_login":"zhuangjianguo"} --> _Requested by **Steedos** · [project thread](https://claude.ai/code/project/chan_018ETKaNwMZCNRYD7D8Q9Ubb?thread=cmsg_018ETKaNwMZCNRYD7D8Q9UbbB5em8iozkeVyx4gPsLp6Qf)_ Fixes #28578 PR 2 of 2. PR 1, #28785, retired Packaged automation's flows half and landed as `0aaad18f`. This PR carries Wanted 1, 2, 4 and 5 and the card's tests. The split is recorded in claim amendment 6561871570. ## 维护者速读 - **改了什么**:设置里的元数据页面全部改为跳转到 Studio 的"全部元数据"区域,每条路由和旧别名都在一跳内到达,`?package`、`?scope`、`?review` 原样保留。数据源例外,仍留在设置。设置导航移除岗位、能力、权限集、声明式共享规则四项。主页移除"对象管理"侧边栏入口和"管理对象"卡片。目录的启用开关移到每个条目自己的页面上。Studio 不再链接到设置的元数据页面。旧的打包自动化书签现在跳到对应软件包的自动化栏。 - **为什么改**:ADR-0146 D1 规定设置不再有元数据编辑器和元数据目录,这些都由 Studio 的"全部元数据"区域承担。开关放在条目页面,依据的是 M-1 裁定 6554738464。 - **风险与回滚**:只有 `setup.access`、没有 `studio.access` 的管理员,今后要在 Studio 里切换这些条目,需要给他们补授 `studio.access`。changeset 里写了这一点。旧书签和外部链接会被重定向,不会失效。回滚就是 revert 本 PR。 - **先看**:`ui/packages/app-shell/src/views/studio-design/setupMetadataRedirect.ts`、`ui/packages/app-shell/src/console/AppContent.tsx`(`SetupMetadataRoute`、`LegacyMetadataRedirect`、`PackagedAutomationRedirect`)、`ui/packages/app-shell/src/views/metadata-admin/CatalogActiveSwitch.tsx`。 - **两分钟验证**:打开 `/apps/setup/metadata/position?scope=environment`,应跳到 `/studio/~all/metadata/position?scope=environment`。打开一个岗位,页面上有"启用"开关。打开 `/apps/setup/metadata/datasource`,仍停留在设置。 - **需要你做的**:确认发布说明里关于 `studio.access` 的提示是否足够。 ## What changes - **Every Setup metadata route redirects** (`@object-ui/app-shell`). All of the `/apps/<app>/metadata` routes, on both `AppContent` branches, render `SetupMetadataRoute`: the index, `_diagnostics`, `:type`, `:type/new`, `:type/:name` and `:type/:name/history`. It navigates to `setupMetadataStudioPath(rest, search, hash)`, which keeps the path below `metadata`, keeps the query, and puts the URL on the leg its query names through `areaLocationRedirect`. That leg is `?package=X` for X's leg, and `?scope=environment` or `?package=all` for `~all`. The area adds no second hop. `LegacyMetadataRedirect` (`component/metadata/{directory,resource/*}`) now goes to Studio directly. The `metadata*` rows leave `APP_ROUTE_CHUNKS`. - **The datasource stays.** `setupMetadataStudioPath` returns `null` for `datasource…`, so those routes render the metadata-admin pages they always did. The area's own `datasource/*` route sends them back to Setup, so redirecting them would loop. - **The console's aliases** (`@object-ui/console`). `ObjectRedirect`, `MetadataRedirect` and `SystemCatalogRedirect` call the same helper, exported from `@object-ui/app-shell`, so `system/objects`, `system/metadata` and `system/{roles,positions,permissions}` land in Studio in one hop. - **Retired Packaged automation bookmarks** (the seat asked for this after #28785). `component/automation/packaged` is a static route ahead of `component/:ns/:name`. It opens `/studio/<package>/automations` with the query kept when `?package=` names a package. When no package is named, it opens `/studio/~all/metadata/flow`, the area's cross-package flow list, because the pillar is per package. - **The review hop.** `DraftReviewNavigator` (the chat's "Review N changes") opens `…/metadata/<type>/<name>?review=1` in Studio. - **Nav and Home.** `plugin-security` drops its `group_access_control` contribution (`nav_positions`, `nav_capabilities`, `nav_permission_sets`), and `plugin-sharing` drops `nav_declared_sharing_rules`. Their labels leave the four locales and the source-hash files, and the four ids join the dead-key tombstone. `UnifiedSidebar` drops `sys-objects`, and `QuickActions` drops the Manage Objects card. - **The Active switch moves to the item's page** (M-1 ruling A, comment 6554738464). The list's switch, its confirm dialog and its ledger cell move into `CatalogActiveSwitch.tsx`. `CatalogItemActiveSwitch` is that switch for one item: it reads the ledger, runs the holder-count confirm for permission sets and positions, writes, and toasts. The area's item pages mount it: position and sharing rule through `ResourceEditPage`'s area sections, and permission set through `PermissionMatrixEditor`. The area's list keeps its column. - **Studio stops linking into Setup.** `BuilderLanding` drops `overlayPath` and the "Open in Setup" overlay link, along with its two Studio-namespace strings. `StudioReadOnlyLink` links the item's page in the area. - **Live specs** (`ui/e2e/live`). `studio-object-designer`, `studio-editor` and the nightly `declared-sharing-rules-reach-13091` now open Studio URLs. ## Why ADR-0146 D1 says Setup carries no metadata editor and no metadata catalog, and Studio's "All metadata" area (#28561) serves those pages. Old Setup links should land there rather than break. The datasource is runtime configuration, so it stays in Setup. ## Tests - New `AppContent.setupMetadataStudio-28578.test.tsx` holds the redirect table over every route and alias. It runs on the with-app branch (as `setup` and as `crm`) and the zero-app branch. Every row asserts the whole chain, which shows one hop. The table covers `?package`, `?scope`, `?review` and the hash. It checks that the datasource routes and the `?type=datasource` alias stay on their pages, and that `metadata/package/*` keeps its target. It pins the Packaged automation bookmark, with a control that `automation:packaged-actions` still resolves. - New `setupMetadataRedirect.test.ts` covers the helper. It includes a check that each target is already on its leg, so the area adds no second hop, and it covers `packagedAutomationStudioPath`. - New `noSetupMetadataLink-28578.test.ts` is the source grep pin. It reads every non-test file under `views/studio-design/` with comments masked and refuses any `/apps/<app>/metadata` spelling. The datasource is exempt. The matcher has a control. Run against the `272fec05` copies of `StudioDesignSurface.tsx` and `BuilderLanding.tsx`, it catches the base's links. - New `CatalogActiveSwitch.itemPage-28578.test.tsx` checks the switch for each type. Off asks with the holder count, Cancel writes nothing, and on writes at once. A sharing rule writes with no holder read. A viewer who cannot author gets no click, and a refused read is stated in words. A source pin checks where the item pages mount the switch. - Inverted nav pins: - `people-org-assignment-nav-contribution.test.ts`: the catalog entries are gone; - `systemNavObjectsHop.test.tsx`: there is no Object Manager entry; - `systemNavSettingsTarget.test.tsx`: eight entries; - `QuickActions.settingsTarget.test.tsx`: there is no Manage Objects card. - The extended tombstone has four ids. - Route tests are re-pointed at Studio: `pseudoRouteSegments`, `noAppComponentRoutes`, `bootRedirectCoverage`, `emptyNavigationLanding-12079`, `setupItemRoutesVerdict-12706`, and the console's `legacyRedirects` and `systemHubRoutes`. Studio tests are updated for the removed link: `readonlyRoutes-11808`, `setupExit-12513`, `environmentOverlayCopy-12171`, `StudioReadOnlyLink.overlay-27356` and `metadataAreaHost.gates-28561`. ## Verification Head `50d583ef` on `0aaad18f`. - ui: 332 test files in two locked batches (`--maxWorkers=2`) on the rebased head, 3594 tests, all green. The set is every app-shell and console test that names the touched modules or a Setup metadata URL (`AppContent`, `setupMetadataRedirect`, `UnifiedSidebar`, `QuickActions`, `BuilderLanding`, `StudioReadOnlyLink`, `CatalogActiveSwitch`, `ResourceListPage`, `ResourceEditPage`, `PermissionMatrixEditor`, `catalog-activation`, `apps/setup/metadata`, `automation/packaged`, …). The full app-shell suite is left to CI's Test UI shards. - `@objectstack/platform-objects`: 107 files and 1497 tests. `@objectstack/plugin-security`: 238 files and 5126 tests. `@objectstack/plugin-sharing`: 59 files and 1305 tests. All green. - Type-check: `@object-ui/app-shell` and `@object-ui/console` are green after `turbo run build --filter='@object-ui/console^...'` on the new main. - `node scripts/pm/dispatch-gates.mjs --commands`: 67 commands, 66 exit 0, including `check-sdui-manifest`, `check:i18n` (bundles in sync), `check:platform-checklist`, `check:dual-build-cjs-loads` and `pnpm --dir ui exec vitest run scripts/`. `check-plugin-teardown-shape --self-test` exits 3 because this clone is shallow, so it is left to CI. - `eslint` on the changed ui files: 0 errors. - PR-body gates on this body: `check-changeset-no-major`, `check-adr-0087-registration`, `check-closing-keyword-parity` and `check-partof-closing-keyword` are green. Clause-②: no Metadata-protocol: none ## Human Minimum - [x] 1. Schemas start as Zod; `packages/spec` holds no runtime logic. (`packages/spec` untouched.) - [x] 2. Every name I added uses the casing for its kind. - [x] 3. No formatter ran; `pnpm lint` passes. - [x] 4. One issue, one branch off an up-to-date `main`, one pull request. (PR 2 of 2 for #28578; the split is the seat's call, recorded on the card.) - [x] 5. A change that publishes carries a changeset, and both declaration lines are filled in here and in the changeset. - [x] 6. `packages/spec` touched: n/a. - [x] 7. No hand edits to `content/docs/references/`, `packages/*/CHANGELOG.md` or `content/docs/releases/`. - [x] 8. Title, body and comments are in English, except the 维护者速读 section, which the lane writes in Chinese for the maintainer. - [x] The *Before Submitting* list in CONTRIBUTING.md is done. 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_01QsR2jRKMRpKnN9FkAvSWGr --------- Co-authored-by: Claude <noreply@anthropic.com>
1 parent 3b920f6 commit 67103cc

63 files changed

Lines changed: 1617 additions & 768 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
---
2+
'@object-ui/app-shell': patch
3+
'@object-ui/console': patch
4+
'@object-ui/i18n': patch
5+
'@objectstack/platform-objects': patch
6+
'@objectstack/plugin-security': patch
7+
'@objectstack/plugin-sharing': patch
8+
---
9+
10+
feat(setup): Setup's metadata pages open Studio's All metadata area, the catalog's Active switch moves to each item's page, and Studio stops linking into Setup
11+
12+
Clause-②: no
13+
Metadata-protocol: none
14+
15+
Setup no longer has a metadata editor or a metadata catalog (ADR-0146 D1). Studio's "All metadata" area serves those pages now.
16+
17+
- **Setup's metadata URLs redirect.** Each `/apps/<app>/metadata/...` route opens the same page in Studio's "All metadata" area: the directory, `_diagnostics`, a type's list, an item, its history and its create page. The legacy aliases redirect too: `component/metadata/{directory,resource}` in the shell, and `system/objects`, `system/metadata` and `system/{roles,positions,permissions}` in the console. `?package=`, `?scope=environment` and `?review=1` carry over, and each URL lands in one hop on the leg its query names.
18+
- **The datasource stays in Setup.** Its routes render Setup's pages as before. It is runtime configuration, not metadata authoring, and the area sends datasource URLs back to Setup.
19+
- **A bookmark of the retired Setup › Packaged automation page lands in Studio.** `/apps/<app>/component/automation/packaged?package=<id>` opens that package's Automations pillar, where a packaged flow's switch and New similar are, with the query kept. With no package named, it opens the area's cross-package list of flows.
20+
- **The catalog entries leave Setup.** Positions, Capabilities, Permission Sets and Declared Sharing Rules leave Setup's navigation, and their labels are retired in all four locales. Home loses the "Manage Objects" quick action, and the sidebar loses its Objects entry.
21+
- **The Active switch moves to the item's page.** A permission set, a position or a declared sharing rule is now switched on and off on its own page in the area. It is the same switch the catalog list had: switching off asks first and names how many users lose the access, and switching on writes at once. The area's type lists keep their switch column. **An admin with `setup.access` but no `studio.access` now switches these items in Studio.** Grant `studio.access` to anyone who managed the catalog from Setup.
22+
- **Studio stops linking into Setup.** The landing page's environment-overlay link is gone. The read-only item link and the chat's "Review changes" now open the item in Studio's area.

‎docs/adr/0126-packaged-metadata-customization-model.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -405,7 +405,7 @@ callers first, or don't), and preserves "packaged code calls what it names".
405405

406406
- **Leaning D2 — a Setup page for packaged automation** (final call rides this ADR's merge):
407407
packaged flows with their activation state and the enable/disable and clone actions,
408-
contributed the way `nav_permission_sets` is (`packages/plugins/plugin-security/src/security-plugin.ts#nav_permission_sets`). The maintainer
408+
contributed the way "nav_permission_sets" is (`packages/plugins/plugin-security/src/security-plugin.ts`; 2026-11-02 note: that entry is retired under N-28, #28578, and §7.4's surface moved per ADR-0146 D4). The maintainer
409409
corrected the record here: automation UI is **Studio-only today** (`packages/platform-objects/src/apps/studio.app.ts`),
410410
so this page is new work, and the Setup permission-set page is the precedent shape. Studio
411411
keeps the editing; Setup gets the operational state. Minimum honest content per packaged flow:

‎packages/platform-objects/src/apps/translations/en.ts‎

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -95,11 +95,7 @@ export const en: TranslationData = {
9595
nav_permission_set_assignment: { label: 'Permission Set Assignment' },
9696

9797
// Access Control
98-
nav_positions: { label: 'Positions' },
99-
nav_capabilities: { label: 'Capabilities' },
100-
nav_permission_sets: { label: 'Permission Sets' },
10198
nav_sharing_rules: { label: 'Sharing Rules' },
102-
nav_declared_sharing_rules: { label: 'Declared Sharing Rules' },
10399
nav_record_shares: { label: 'Record Shares' },
104100
nav_queues: { label: 'Queues' },
105101
nav_queue_members: { label: 'Queue Members' },

‎packages/platform-objects/src/apps/translations/es-ES.source-hashes.ts‎

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -92,11 +92,7 @@ export const esESSourceHashes: Readonly<Record<string, string>> = {
9292
'apps.setup.navigation.nav_invitations.label': '4ebb9fd13de7a546',
9393
'apps.setup.navigation.nav_position_holders.label': '627cacb50fd1b0d8',
9494
'apps.setup.navigation.nav_permission_set_assignment.label': 'fcf7d1b69ee9c298',
95-
'apps.setup.navigation.nav_positions.label': '517a2743f949b5f0',
96-
'apps.setup.navigation.nav_capabilities.label': '0b59005e10add41f',
97-
'apps.setup.navigation.nav_permission_sets.label': '4addfe2b8b28b78a',
9895
'apps.setup.navigation.nav_sharing_rules.label': 'ceaa66fa5f1df4ad',
99-
'apps.setup.navigation.nav_declared_sharing_rules.label': 'a3371ec9975d5b0f',
10096
'apps.setup.navigation.nav_record_shares.label': 'e261d340ceb25b9a',
10197
'apps.setup.navigation.nav_sso_providers.label': '7b06b6a6abf53ba4',
10298
'apps.setup.navigation.nav_api_keys.label': '8cda9851248b0490',

‎packages/platform-objects/src/apps/translations/es-ES.ts‎

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -62,11 +62,7 @@ export const esES: TranslationData = {
6262
nav_position_holders: { label: 'Titulares de posiciones' },
6363
nav_permission_set_assignment: { label: 'Asignación de conjuntos de permisos' },
6464

65-
nav_positions: { label: 'Posiciones' },
66-
nav_capabilities: { label: 'Capacidades' },
67-
nav_permission_sets: { label: 'Conjuntos de Permisos' },
6865
nav_sharing_rules: { label: 'Reglas de Compartición' },
69-
nav_declared_sharing_rules: { label: 'Reglas de Compartición Declaradas' },
7066
nav_record_shares: { label: 'Registros Compartidos' },
7167
nav_queues: { label: 'Colas' },
7268
nav_queue_members: { label: 'Miembros de Colas' },

‎packages/platform-objects/src/apps/translations/ja-JP.source-hashes.ts‎

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -92,11 +92,7 @@ export const jaJPSourceHashes: Readonly<Record<string, string>> = {
9292
'apps.setup.navigation.nav_invitations.label': '4ebb9fd13de7a546',
9393
'apps.setup.navigation.nav_position_holders.label': '627cacb50fd1b0d8',
9494
'apps.setup.navigation.nav_permission_set_assignment.label': 'fcf7d1b69ee9c298',
95-
'apps.setup.navigation.nav_positions.label': '517a2743f949b5f0',
96-
'apps.setup.navigation.nav_capabilities.label': '0b59005e10add41f',
97-
'apps.setup.navigation.nav_permission_sets.label': '4addfe2b8b28b78a',
9895
'apps.setup.navigation.nav_sharing_rules.label': 'ceaa66fa5f1df4ad',
99-
'apps.setup.navigation.nav_declared_sharing_rules.label': 'a3371ec9975d5b0f',
10096
'apps.setup.navigation.nav_record_shares.label': 'e261d340ceb25b9a',
10197
'apps.setup.navigation.nav_sso_providers.label': '7b06b6a6abf53ba4',
10298
'apps.setup.navigation.nav_api_keys.label': '8cda9851248b0490',

‎packages/platform-objects/src/apps/translations/ja-JP.ts‎

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -62,11 +62,7 @@ export const jaJP: TranslationData = {
6262
nav_position_holders: { label: 'ポジション保持者' },
6363
nav_permission_set_assignment: { label: '権限セットの割り当て' },
6464

65-
nav_positions: { label: 'ポジション' },
66-
nav_capabilities: { label: 'ケイパビリティ' },
67-
nav_permission_sets: { label: '権限セット' },
6865
nav_sharing_rules: { label: '共有ルール' },
69-
nav_declared_sharing_rules: { label: '宣言済みの共有ルール' },
7066
nav_record_shares: { label: 'レコード共有' },
7167
nav_queues: { label: 'キュー' },
7268
nav_queue_members: { label: 'キューメンバー' },

‎packages/platform-objects/src/apps/translations/setup-nav-dead-key-tombstone.test.ts‎

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,20 @@
5757
// entry id (example apps, docs, test fixtures) — so
5858
// for that one the grep is no evidence, and the
5959
// assertions below are the whole claim.
60+
// nav_positions the Setup metadata catalog (ADR-0146 D1, M-1
61+
// nav_capabilities ruling A): Setup carries no metadata catalog.
62+
// nav_permission_sets The four entries opened the registry types'
63+
// nav_declared_sharing_ environment-scope lists, which Studio's "All
64+
// rules metadata" area serves now, with the on/off switch
65+
// on each item's page; Setup's URLs redirect there.
66+
// The first three were plugin-security's, the last
67+
// plugin-sharing's; both depend on this package, so
68+
// the declaring side is pinned in their own tests.
69+
// Measured differently: the grep answers zero for
70+
// `nav_capabilities` and `nav_declared_sharing_rules`
71+
// but not for the other two, which fixtures and an
72+
// ADR still spell, so for those the assertions below
73+
// are the whole claim.
6074
// nav_packaged_automation Setup › Packaged automation (ADR-0146 D11): its
6175
// flows half moved into Studio (D4), and its actions
6276
// half is its own entry, `nav_packaged_actions`.
@@ -100,10 +114,14 @@ const DEAD_SETUP_NAV_IDS = [
100114
'nav_accounts',
101115
'nav_approval_processes',
102116
'nav_audit_log_browser',
117+
'nav_capabilities',
118+
'nav_declared_sharing_rules',
103119
'nav_device_codes',
104120
'nav_jwks',
105121
'nav_metadata',
106122
'nav_packaged_automation',
123+
'nav_permission_sets',
124+
'nav_positions',
107125
'nav_user_preferences',
108126
'nav_verifications',
109127
] as const;

‎packages/platform-objects/src/apps/translations/zh-CN.source-hashes.ts‎

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -92,11 +92,7 @@ export const zhCNSourceHashes: Readonly<Record<string, string>> = {
9292
'apps.setup.navigation.nav_invitations.label': '4ebb9fd13de7a546',
9393
'apps.setup.navigation.nav_position_holders.label': '627cacb50fd1b0d8',
9494
'apps.setup.navigation.nav_permission_set_assignment.label': 'fcf7d1b69ee9c298',
95-
'apps.setup.navigation.nav_positions.label': '517a2743f949b5f0',
96-
'apps.setup.navigation.nav_capabilities.label': '0b59005e10add41f',
97-
'apps.setup.navigation.nav_permission_sets.label': '4addfe2b8b28b78a',
9895
'apps.setup.navigation.nav_sharing_rules.label': 'ceaa66fa5f1df4ad',
99-
'apps.setup.navigation.nav_declared_sharing_rules.label': 'a3371ec9975d5b0f',
10096
'apps.setup.navigation.nav_record_shares.label': 'e261d340ceb25b9a',
10197
'apps.setup.navigation.nav_sso_providers.label': '7b06b6a6abf53ba4',
10298
'apps.setup.navigation.nav_api_keys.label': '8cda9851248b0490',

‎packages/platform-objects/src/apps/translations/zh-CN.ts‎

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -65,11 +65,7 @@ export const zhCN: TranslationData = {
6565
nav_position_holders: { label: '岗位持有人' },
6666
nav_permission_set_assignment: { label: '权限集分配' },
6767

68-
nav_positions: { label: '岗位' },
69-
nav_capabilities: { label: '能力' },
70-
nav_permission_sets: { label: '权限集' },
7168
nav_sharing_rules: { label: '共享规则' },
72-
nav_declared_sharing_rules: { label: '已声明的共享规则' },
7369
nav_record_shares: { label: '记录共享' },
7470
nav_queues: { label: '队列' },
7571
nav_queue_members: { label: '队列成员' },

0 commit comments

Comments
 (0)