Skip to content
This repository was archived by the owner on Oct 26, 2026. It is now read-only.

fix(console, app-shell): localise API Console, Public Forms, Integrations, AI Approvals and the datasource page (objectui#13460) - #13489

Merged
objectstack-fleet[bot] merged 2 commits into
mainfrom
claude/project-thread-notxiv
Oct 25, 2026
Merged

objectstack-fleet[bot] merged 2 commits into
mainfrom
claude/project-thread-notxiv

Conversation

@objectstack-fleet

Copy link
Copy Markdown
Contributor

Requested by Elon · project thread

Part of objectstack-ai/objectstack#25916
Clause-②: no
Metadata-protocol: none

Claim: objectui#13460 comment 6392274945, amended by comment 6392316827 (file surface adds packages/app-shell/src/views/metadata-admin/i18n.ts). Seat: domain:ui#4.

What changed

Four routed console pages imported nothing from @object-ui/i18n, and the Studio datasource page drew its copy as English literals, so a zh / ja / ar operator got English on these screens.

  • Developer → API Console (ApiConsolePage.tsx), Developer → Public Forms (PublicFormsPage.tsx), Developer → Integrations & APIs (IntegrationsPage.tsx) and System → AI Approvals (AiPendingActionsPage.tsx) read console.developer.apiConsole.*, console.developer.publicForms.*, console.developer.integrations.* and console.system.aiApprovals.* through useObjectTranslation. 108 new keys, translated in all ten packs (no English copies). Cancel / Save / Refresh / Actions reuse common.*. Each call carries the en value as its inline defaultValue (held byte-identical by pnpm check:i18n-keys), so a provider-less mount and every existing English test read exactly what they read before.
  • A sentence with an inline element (a bold action name, a <code> key) is ONE translated string: the element's {{slot}} is filled with a private-use mark and the sentence is split on it, so each language places the element (ja and ko put the action after its object). Helper: apps/console/src/lib/inlineSlots.tsx (withSlots), the same technique as element:metadata_viewer's chips (objectui#12910).
  • Aria names that used to be glued as `Copy ${label}` are whole translated keys (copyBaseUrl, copySample); toasts likewise (copiedUrl, copiedIframe, copiedReact).
  • Setup → Datasources (DatasourceResourcePage.tsx) reads 55 new engine.datasource.* rows in the Studio table (metadata-admin/i18n.ts, en-US + zh-CN). That page already read engine.*, and packages/i18n/README.md § "Scope — the engine.* carve-out" keeps that namespace out of the ten packs. Covered: heading, toolbar, empty state (action slot), status chips, row actions, the create/edit dialog including the Schema mode options, the sync dialog, and the toasts. The driver config schema's enum option values are untouched (objectui#13353).
  • Left as written on purpose: the cURL / iframe / React snippets (code), HTTP verbs, paths and status codes, example slugs and paths in placeholders (contact-us, /thanks, my_database, /api/v1/...), server messages, and the redirect refusal (the spec's own prose).
  • Typography: three new English values spell the ellipsis U+2026 (Search endpoints…, Discovering APIs…, Sending request…; they were ...), because ellipsis-glyph-3878 holds every pack value to it.

Tests

  • apps/console/src/pages/developer/consolePagesLocale-13460.test.tsx (new): under zh each page draws its heading and copy from the zh pack (guarded as real Han-script rows, not English copies); the three slotted sentences render with the element where the zh string puts it and no {{ or slot mark leaks; control: with no provider each page still reads its English.
  • packages/app-shell/src/views/metadata-admin/datasource/DatasourceResourcePage.locale-13460.test.tsx (new): zh heading, empty state with its action slot, status chip, row actions and the create dialog read the zh rows; en control.
  • DatasourceResourcePage.selectPlaceholderLocale-11252.test.tsx: finds the New datasource button by its locale's row (the button is now translated). ApiConsolePage.requestPreset-10591.test.tsx: the Sending request… glyph.

Verification (local, objectui main c85408f + this branch)

  • turbo run type-check for @object-ui/console, @object-ui/app-shell, @object-ui/i18n (38 tasks incl. deps): pass.
  • vitest run packages/i18n/: 87 files, 1353 passed.
  • vitest run over every test file importing the five pages, inlineSlots, or reading the Studio table's source (32 files): 559 passed.
  • node scripts/check-i18n-call-site-keys.mjs, check-i18n-en-drift.mjs, check-i18n-dead-keys.mjs, check-i18n-designer-table-parity.mjs: exit 0.
  • eslint on the touched sources: 0 errors, and the same warning set as main (no new findings).
  • check-changeset-presence.mjs, check-changeset-no-major.mjs, check:new-line-citations: pass.
  • NOT MEASURED locally, left to CI: the sharded full pnpm test; check:eager-closure (the eager en catalogue grows by the new keys; i18n-locale-en ceiling is in scripts/check-eager-closure-budget.mjs); check:readme-exports (needs every dist).

Acceptance notes

  • Out of this PR by the claim, left on the card: objectui#13353 (enum option labels), moving dev-only surfaces under dev/, and the remaining literals on other surfaces (AuditLogPage, FlowRunsPage, ShareDialog, …).

  • The Studio table covers en + zh only (the carve-out), so the datasource page renders English in the other eight languages, as every other Studio screen does.

  • Overlap: the objectui#13461 card thread may add keys to the same ten packs; whichever lands second merges main.

  • Adds no product-specific widget, dialog, hook or string (see AGENTS.md › Product-neutral renderer)

🤖 Generated with Claude Code

https://claude.ai/code/session_01QY7vnZv639mvLbooY6nBKU

…atasource page (objectui#13460)

API Console, Public Forms, Integrations & APIs and AI Approvals read
console.developer.* / console.system.* keys, translated in all ten
packs; the Studio datasource page reads engine.datasource.* rows (en-US
and zh-CN, the engine.* carve-out). Inline bold / code elements are
slots in one translated sentence (apps/console/src/lib/inlineSlots.tsx).

Part of #13460

Claude-Session: https://claude.ai/code/session_01QY7vnZv639mvLbooY6nBKU
Co-authored-by: Claude <noreply@anthropic.com>
…; ellipsis glyph in the new keys (objectui#13460)

- consolePagesLocale-13460: the four routed pages under zh read the zh
  pack, slotted sentences place their element where the zh string puts
  it, and a provider-less mount still reads English.
- DatasourceResourcePage.locale-13460: the datasource page reads its
  engine.datasource.* zh rows; en control.
- The new values spell the ellipsis U+2026 (ellipsis-glyph-3878); the de
  empty-state sentence drops its quote pair so the de-quote-pairing
  census count stays as pinned.
- selectPlaceholderLocale-11252 finds the New datasource button by its
  locale's row now that the button is translated.

Part of #13460

Claude-Session: https://claude.ai/code/session_01QY7vnZv639mvLbooY6nBKU
Co-authored-by: Claude <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown
Contributor

✅ Console Performance Budget

Metric Value Budget
Eager closure (gzip, 85 chunks) 3036.6 KB 3496.0 KB
Main entry chunk (gzip) 80.3 KB 350 KB
Entry file index-ChKTeolq.js —
Status PASS —

The eager closure is every chunk the entry reaches through static imports — what the browser fetches and parses before the app renders. The entry chunk on its own is a small fraction of it.


📦 Bundle Size Report

Package Size Gzipped
app-shell (buildIdentity.js) 0.80KB 0.49KB
app-shell (consoleActionDispatch.js) 0.20KB 0.19KB
app-shell (index.js) 21.41KB 7.90KB
app-shell (runtime-config.js) 24.52KB 8.48KB
app-shell (types.js) 0.01KB 0.04KB
app-shell (urlParams.js) 10.11KB 3.87KB
auth (ActiveOrganizationStorage.js) 27.95KB 10.04KB
auth (AuthContext.js) 0.31KB 0.24KB
auth (AuthGuard.js) 2.07KB 1.00KB
auth (AuthProvider.js) 45.59KB 12.03KB
auth (AuthShell.js) 3.49KB 1.40KB
auth (ForgotPasswordForm.js) 12.21KB 3.45KB
auth (LoginForm.js) 20.67KB 6.12KB
auth (PreviewBanner.js) 0.90KB 0.50KB
auth (RegisterForm.js) 6.72KB 2.24KB
auth (SocialSignInButtons.js) 9.74KB 3.94KB
auth (UserMenu.js) 3.39KB 1.21KB
auth (auth-gate-events.js) 1.62KB 0.83KB
auth (authStyles.js) 5.27KB 1.86KB
auth (createAuthClient.js) 42.84KB 11.66KB
auth (createAuthenticatedFetch.js) 8.54KB 3.46KB
auth (index.js) 3.63KB 1.64KB
auth (invitation-status.js) 1.22KB 0.70KB
auth (org-roles.js) 8.84KB 3.61KB
auth (phone-identifier.js) 1.11KB 0.66KB
auth (types.js) 0.59KB 0.35KB
auth (useAuth.js) 5.30KB 1.02KB
auth (useWorkspaceAdminStatus.js) 11.08KB 4.58KB
collaboration (CommentThread.js) 27.26KB 8.03KB
collaboration (LiveCursors.js) 3.17KB 1.27KB
collaboration (PresenceAvatars.js) 6.28KB 2.60KB
collaboration (PresenceProvider.js) 2.79KB 1.13KB
collaboration (commentAuthorship.js) 1.39KB 0.78KB
collaboration (index.js) 1.93KB 0.85KB
collaboration (useCollaborationTranslation.js) 6.50KB 2.52KB
collaboration (useCommentSearch.js) 1.98KB 0.88KB
collaboration (useConflictResolution.js) 7.75KB 1.86KB
collaboration (useMentionNotifications.js) 1.81KB 0.68KB
collaboration (usePresence.js) 6.33KB 1.84KB
collaboration (useRealtimeSubscription.js) 7.91KB 2.01KB
components (index.js) 614.94KB 150.52KB
core (index.js) 10.51KB 4.16KB
create-plugin (index.js) 27.92KB 9.50KB
data-objectstack (index.js) 253.04KB 70.68KB
fields (index.js) 295.90KB 75.88KB
i18n (LocalizationContext.js) 2.92KB 1.42KB
i18n (builtinAggregateLabels.js) 0.86KB 0.49KB
i18n (currency.js) 2.59KB 1.22KB
i18n (fallbackInterpolation.js) 6.25KB 2.77KB
i18n (i18n.js) 8.87KB 3.64KB
i18n (index.js) 5.52KB 2.39KB
i18n (pickLocalized.js) 9.86KB 3.95KB
i18n (provider.js) 39.35KB 12.88KB
i18n (translateFn.js) 0.20KB 0.18KB
i18n (useDisplayLocale.js) 3.52KB 1.76KB
i18n (useObjectLabel.js) 36.87KB 9.88KB
i18n (useSafeTranslation.js) 7.14KB 2.92KB
layout (index.js) 41.17KB 11.96KB
mobile (MobileProvider.js) 0.92KB 0.49KB
mobile (ResponsiveContainer.js) 0.94KB 0.38KB
mobile (breakpoints.js) 1.51KB 0.70KB
mobile (createOfflineDataSource.js) 5.61KB 1.75KB
mobile (index.js) 1.99KB 0.87KB
mobile (offlineQueue.js) 3.91KB 1.35KB
mobile (pwa.js) 0.97KB 0.49KB
mobile (serviceWorker.js) 1.48KB 0.62KB
mobile (serviceWorkerSource.js) 3.41KB 1.48KB
mobile (useBreakpoint.js) 1.54KB 0.65KB
mobile (useGesture.js) 6.96KB 1.98KB
mobile (useOfflineSync.js) 1.99KB 0.72KB
mobile (usePullToRefresh.js) 6.62KB 2.45KB
mobile (useResponsive.js) 0.72KB 0.42KB
mobile (useSpecGesture.js) 5.52KB 2.10KB
mobile (useTouchTarget.js) 1.01KB 0.54KB
permissions (MePermissionsProvider.js) 15.35KB 5.51KB
permissions (PermissionContext.js) 0.31KB 0.25KB
permissions (PermissionGuard.js) 0.89KB 0.45KB
permissions (PermissionProvider.js) 6.82KB 2.38KB
permissions (ServerReadScope.js) 4.03KB 1.82KB
permissions (discardProofCache.js) 1.04KB 0.55KB
permissions (evaluator.js) 8.33KB 3.07KB
permissions (index.js) 0.99KB 0.43KB
permissions (store.js) 0.91KB 0.42KB
permissions (useFieldPermissions.js) 1.28KB 0.53KB
permissions (usePermissions.js) 4.83KB 2.27KB
plugin-ai (index.js) 16.01KB 3.91KB
plugin-calendar (index.js) 55.31KB 16.16KB
plugin-charts (index.js) 88.30KB 24.33KB
plugin-chatbot (core.js) 5.22KB 2.18KB
plugin-chatbot (index.js) 237.93KB 56.26KB
plugin-dashboard (index.js) 147.15KB 39.95KB
plugin-designer (index.js) 232.83KB 50.01KB
plugin-detail (index.js) 268.92KB 71.56KB
plugin-editor (index.js) 2.21KB 1.04KB
plugin-form (index.js) 185.46KB 48.48KB
plugin-gantt (index.js) 178.19KB 45.06KB
plugin-grid (index.js) 277.62KB 77.39KB
plugin-kanban (index.js) 64.27KB 19.81KB
plugin-list (index.js) 149.51KB 39.15KB
plugin-map (index.js) 27.54KB 9.10KB
plugin-markdown (index.js) 13.79KB 4.79KB
plugin-report (index.js) 46.42KB 13.06KB
plugin-timeline (index.js) 39.74KB 12.00KB
plugin-tree (index.js) 15.25KB 5.38KB
plugin-view (index.js) 93.37KB 24.00KB
providers (DataSourceProvider.js) 0.75KB 0.39KB
providers (MetadataProvider.js) 1.37KB 0.59KB
providers (ThemeProvider.js) 1.90KB 0.85KB
providers (UploadProvider.js) 12.07KB 3.68KB
providers (index.js) 0.45KB 0.23KB
providers (types.js) 0.01KB 0.04KB
react-runtime (index.js) 5.62KB 2.34KB
react (LazyPluginLoader.js) 4.47KB 1.63KB
react (SchemaRenderer.js) 129.13KB 42.23KB
react (data-invalidation.js) 5.05KB 2.08KB
react (index.js) 4.71KB 2.11KB
react (schema-input.js) 4.31KB 2.07KB
react (spec-input.js) 0.20KB 0.18KB
sdui-parser (body-dialect.js) 4.50KB 1.99KB
sdui-parser (codegen.js) 9.45KB 3.76KB
sdui-parser (dashboard-widget-options.js) 3.07KB 1.30KB
sdui-parser (index.js) 7.30KB 3.12KB
sdui-parser (input-type.js) 2.84KB 1.40KB
sdui-parser (parse.js) 25.28KB 7.81KB
sdui-parser (provenance.js) 3.84KB 1.90KB
sdui-parser (types.js) 0.29KB 0.24KB
sdui-parser (validate.js) 23.87KB 7.83KB
types (ai.js) 4.39KB 2.17KB
types (api-types.js) 0.20KB 0.18KB
types (app.js) 4.12KB 1.61KB
types (authoring-nodes.js) 0.20KB 0.19KB
types (base.js) 0.20KB 0.18KB
types (blocks.js) 0.20KB 0.18KB
types (cloud.js) 0.20KB 0.18KB
types (complex.js) 4.44KB 2.07KB
types (crud.js) 0.20KB 0.18KB
types (dashboard-filter-alias.js) 6.23KB 2.74KB
types (dashboard-widget-layout.js) 2.06KB 0.96KB
types (data-display.js) 3.75KB 1.85KB
types (data-protocol.js) 0.20KB 0.19KB
types (data.js) 0.20KB 0.18KB
types (designer.js) 1.85KB 0.85KB
types (disclosure.js) 0.20KB 0.18KB
types (error-code.js) 1.54KB 0.88KB
types (expression.js) 0.20KB 0.18KB
types (feedback.js) 0.20KB 0.18KB
types (field-types.js) 1.13KB 0.65KB
types (form.js) 0.20KB 0.18KB
types (http-inflight.js) 8.87KB 3.73KB
types (http-retry.js) 4.32KB 2.02KB
types (icon-key-migration.js) 4.26KB 1.63KB
types (index.js) 5.78KB 2.70KB
types (layout.js) 0.20KB 0.18KB
types (managed-by.js) 0.19KB 0.18KB
types (mobile.js) 5.00KB 2.39KB
types (navigation.js) 0.20KB 0.18KB
types (node-slots.js) 7.18KB 2.34KB
types (objectql.js) 0.20KB 0.18KB
types (overlay.js) 0.20KB 0.18KB
types (permissions.js) 2.52KB 1.31KB
types (plugin-scope.js) 0.20KB 0.18KB
types (product-blocks.js) 0.20KB 0.19KB
types (record-approval-decision.js) 0.20KB 0.20KB
types (record-components.js) 0.20KB 0.19KB
types (record-panels.js) 0.20KB 0.19KB
types (record-semantics.js) 1.28KB 0.67KB
types (registry.js) 0.20KB 0.18KB
types (reports.js) 0.20KB 0.18KB
types (select-option.js) 0.20KB 0.19KB
types (spec-report.js) 4.99KB 1.96KB
types (spec-ui-namespace.js) 0.20KB 0.19KB
types (strict-authoring-face.js) 19.93KB 7.26KB
types (system-fields.js) 3.33KB 1.54KB
types (theme.js) 6.28KB 2.87KB
types (ui-action.js) 8.48KB 3.50KB
types (views.js) 0.20KB 0.18KB
types (widget.js) 0.20KB 0.18KB

Size Limits

  • ✅ Core packages should be < 50KB gzipped
  • ✅ Component packages should be < 100KB gzipped
  • ⚠️ Plugin packages should be < 150KB gzipped

@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

席位核对 — ACCEPT · PR #13489 @ 20d545b661cab78060d3b9a61f95fb42c275803b · domain:ui#4 · 2026-10-25T02:46Z

Reviewer of record: session_01XWGTsmqrtrt1Zqh1ioWqsT (seat 4). Implemented-by: session_01QY7vnZv639mvLbooY6nBKU on claude/project-thread-notxiv. Card objectui#13460, claim 6392274945, amendment 6392316827, report 6392482434.

  1. Shape: draft, base main, body says Part of objectstack-ai/objectstack#25916, and no closing keyword sits next to any open card. 22 files: the four routed pages, DatasourceResourcePage.tsx, metadata-admin/i18n.ts (the engine.datasource.* rows the amendment added), the ten locale packs, the tests, one changeset, and one new helper, apps/console/src/lib/inlineSlots.tsx (see 4).
  2. Premise measured: the four pages imported nothing from @object-ui/i18n. Each now reads console.developer.* / console.system.* through useObjectTranslation, with the en value as an inline defaultValue, so a provider-less mount and the existing English tests still read the same English. The datasource page reads engine.datasource.* (en + zh), per the engine.* carve-out. Its enum option values are untouched (objectui#13353).
  3. Gates on this head: 33 check-runs success (Lint, Type Check, Test shards 1–16 and the aggregate Test, Build & E2E, Build Docs, Repo Gates, the changeset family, Line Citation Gate, Governed Surface Queue Guard, Bundle Analysis, Test (dist pins), label, Live E2E (informational)) and 3 skipped (coverage jobs, dependabot). mergeable_state: clean. Console Performance Budget: PASS.
  4. Accepted deviations: inlineSlots.tsx sits outside the claimed surface. It lets a sentence with an inline <strong> / <code> be ONE translated string, so ja and ko can place the element themselves; the same technique as element:metadata_viewer's chips (objectui#12910). It is console-private (not published), names no product, and serves only these pages. One existing test now clicks "New datasource" through the key, not the English literal.
  5. Out of scope, left on the card: objectui#13353 (enum option labels); moving dev-only surfaces under dev/; the remaining literals on other surfaces (AuditLogPage, FlowRunsPage, ShareDialog, …). After landing, the card returns to pm:queue with that list.
  6. Landing: not governed (no .claude/**, skills/**, AGENTS.md, workflows). Changeset: @object-ui/console, @object-ui/app-shell, @object-ui/i18n patch, Clause-② no / Metadata-protocol none. The seat read it against the diff and it matches. The maintainer's standing landing word was given in this seat's project thread at 2026-10-25T01:48Z, so the seat lands it.

Generated by Claude Code

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants