Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions .changeset/25922-studio-i18n-flow-and-chrome.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
---
'@object-ui/i18n': patch
---

feat(i18n): the flow designer and the rest of the Studio chrome move into the `studio` namespace

Clause-②: no
Metadata-protocol: none

- **Sixth slice of the move ruled on objectstack#25922** (6431032267, Q2 = A; kept by 6431234244). Every row still left in `@object-ui/app-shell`'s private designer table, except `engine.translationPreview.*`, now lives in `@object-ui/i18n/namespaces/studio`, text unchanged: the flow designer (`engine.flowSim.*`, `engine.flowCanvas.*`, `engine.flowRuns.*` and the other `engine.flow*` families), the page-block canvas, the doc and book previews, `engine.studio.inspector.*` and the remaining Studio chrome (538 keys in `en`, 583 in `zh`). The `engine.flowNode.*` and `engine.enum.*` rows stay zh-only, as before: their English is the flow node descriptor or the enum value itself. Studio reads the same strings; a Chinese viewer sees these labels in English for the moment the `zh` catalogue takes to load, as with the earlier slices. No export changes.
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,11 @@ import { fieldRuleRootIssue, validateRlsPredicateEnforceability } from '@objects
import { t, tFormat } from './i18n';
import { CelPredicateField } from './CelPredicateField';
import { lintCelPredicate, type CelSchemaHint } from './celAuthoring';
// The designer rows this suite reads in zh live in `@object-ui/i18n`'s `studio`
// namespace, whose `zh` catalogue is fetched on demand (objectstack#25922).
// Resident before any case, so the zh rows below read synchronously.
import { loadStudioCatalogue } from '@object-ui/i18n/namespaces/studio';
await loadStudioCatalogue('zh');

afterEach(cleanup);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,13 @@

import { describe, it, expect } from 'vitest';
import { translateNodeLabel, translateNodeHint } from './i18n';
// The designer rows this suite reads in zh live in `@object-ui/i18n`'s `studio`
// namespace, whose `zh` catalogue is fetched on demand (objectstack#25922).
// Resident before any case: this file runs in the `unit` project, whose shared
// module graph would otherwise let it pass only when another file had loaded
// `zh` first.
import { loadStudioCatalogue } from '@object-ui/i18n/namespaces/studio';
await loadStudioCatalogue('zh');

/**
* The framework's own strings for this node type, copied here ONLY as the
Expand Down
1,331 changes: 4 additions & 1,327 deletions ui/packages/app-shell/src/views/metadata-admin/i18n.ts

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,11 @@ import { FlowNodeInspector } from './FlowNodeInspector';
import { NODE_PALETTE } from '../previews/flow-canvas-parts';
import { t, type SupportedLocale } from '../i18n';
import type { MetadataSelection } from '../preview-registry';
// The designer rows this suite reads in zh live in `@object-ui/i18n`'s `studio`
// namespace, whose `zh` catalogue is fetched on demand (objectstack#25922).
// Resident before any case, so the zh rows below read synchronously.
import { loadStudioCatalogue } from '@object-ui/i18n/namespaces/studio';
await loadStudioCatalogue('zh');

const ACTIONS_ROUTE = '/api/v1/automation/actions';
let engineActions: unknown[] | null = null;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
// Copyright (c) 2026 ObjectStack. Licensed under the Apache-2.0 license.

/**
* objectstack#25922 slices S2 to S5 — the designer rows that moved into
* objectstack#25922 slices S2 to S6 — the designer rows that moved into
* `@object-ui/i18n`'s `studio` namespace (every `engine.inspector.*` row;
* `engine.packages.*`, `engine.form.*`, `engine.edit.*`; `engine.studio.*` but
* its inspector; the data source pages, the field types and the metadata
* preview panes), and app-shell's `t()` / `tOptional()` still answer every one
* of them the way they did when the rows sat in its own table.
* `engine.packages.*`, `engine.form.*`, `engine.edit.*`; all of
* `engine.studio.*`; the data source pages, the field types, the metadata
* preview panes, the flow designer and the rest of the Studio chrome), and
* app-shell's `t()` / `tOptional()` still answer every one of them the way they
* did when the rows sat in its own table.
*
* What would break it:
* - a row copied back into the app-shell table with a different value — the
Expand Down Expand Up @@ -78,15 +79,66 @@ const FAMILY_FLOOR: Readonly<Record<string, number>> = Object.freeze({
'engine.viewPreview.': 4,
'engine.objectPreview.': 1,
'engine.previewShell.': 1,
// S6 — the rest of the table (engine.translationPreview aside): the flow
// designer, the page-block canvas, the doc and book previews, the Studio
// inspector and the remaining chrome
'engine.studio.inspector.': 30,
'engine.flowSim.': 60,
'engine.flowCanvas.': 20,
'engine.flowRuns.': 18,
'engine.flowPreview.': 15,
'engine.flowScope.': 15,
'engine.flowValidate.': 15,
'engine.flowProblems.': 9,
'engine.flowPalette.': 8,
'engine.flowExpr.': 6,
'engine.flowRef.': 5,
'engine.flowRegion.': 4,
'engine.pageBlockCanvas.': 55,
'engine.list.': 30,
'engine.docPreview.': 25,
'engine.catalog.': 25,
'engine.bookPreview.': 20,
'engine.sharingRule.': 15,
'engine.widgetPicker.': 15,
'engine.layers.': 15,
'engine.diagnostics.': 15,
'engine.directory.': 14,
'engine.draftConflict.': 10,
'engine.validation.': 10,
'engine.position.': 9,
'engine.appNav.': 8,
'engine.embedded.': 7,
'engine.quickfind.': 5,
'engine.badge.': 3,
'engine.fieldsListEditor.': 3,
'engine.typeAction.': 2,
'engine.celTest.': 2,
'engine.sourcePageEditor.': 2,
'engine.condition.': 2,
'engine.celLint.': 1,
'engine.package.': 1,
'engine.breadcrumb.': 1,
'engine.repeater.': 1,
'engine.viewColumnPanes.': 1,
'engine.home.': 1,
'engine.cancel': 1,
'engine.close': 1,
});

/**
* The one zh-only family among the moved rows: the package form's help text,
* whose English is the producer's own `.describe()` sentence and is read
* through `tOptional` (`ZH_ONLY_FAMILIES` in
* `ui/scripts/check-i18n-designer-table-parity.mjs` carries the reason).
* The zh-only families among the moved rows, with the fewest keys each may
* carry. The package form's help text reads its English from the producer's own
* `.describe()` sentence; the flow node labels and hints and the flow enum
* values read theirs from the engine descriptor or the value itself. Each is
* read through `tOptional` or a `lookupString` fallback (`ZH_ONLY_FAMILIES` in
* `ui/scripts/check-i18n-designer-table-parity.mjs` carries the reasons).
*/
const ZH_ONLY_PREFIX = 'engine.packages.form.help.';
const ZH_ONLY_FLOOR: Readonly<Record<string, number>> = Object.freeze({
'engine.packages.form.help.': 9,
'engine.flowNode.': 40,
'engine.enum.': 4,
});

const familyKeys = (prefix: string): string[] => Object.keys(EN).filter((key) => key.startsWith(prefix));

Expand All @@ -110,9 +162,9 @@ describe('moved designer rows answer from the studio namespace (objectstack#2592
expect(wrong).toEqual([]);
});

it('the zh-only package help rows stay optional lookups: zh answers, en finds nothing', () => {
const keys = Object.keys(ZH).filter((key) => key.startsWith(ZH_ONLY_PREFIX));
expect(keys.length).toBeGreaterThanOrEqual(9);
it.each(Object.entries(ZH_ONLY_FLOOR))('%s: the zh-only rows stay optional lookups: zh answers, en finds nothing', (prefix, floor) => {
const keys = Object.keys(ZH).filter((key) => key.startsWith(prefix));
expect(keys.length).toBeGreaterThanOrEqual(floor);
expect(keys.filter((key) => key in EN)).toEqual([]);
expect(keys.filter((key) => tOptional(key, 'zh-CN') !== ZH[key])).toEqual([]);
expect(keys.filter((key) => tOptional(key, 'en-US') !== undefined)).toEqual([]);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,11 @@ import { render, screen, cleanup, fireEvent } from '@testing-library/react';
import { I18nProvider } from '@object-ui/i18n';
import { tFormat } from '../i18n';
import { AppPreview } from './AppPreview';
// The designer rows this suite reads in zh live in `@object-ui/i18n`'s `studio`
// namespace, whose `zh` catalogue is fetched on demand (objectstack#25922).
// Resident before any case, so the zh rows below read synchronously.
import { loadStudioCatalogue } from '@object-ui/i18n/namespaces/studio';
await loadStudioCatalogue('zh');

afterEach(cleanup);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,11 @@ import { I18nProvider } from '@object-ui/i18n';
import { MetadataCtx } from '@object-ui/react';

import { AppNavCanvas } from './AppNavCanvas';
// The designer rows this suite reads in zh live in `@object-ui/i18n`'s `studio`
// namespace, whose `zh` catalogue is fetched on demand (objectstack#25922).
// Resident before any case, so the zh rows below read synchronously.
import { loadStudioCatalogue } from '@object-ui/i18n/namespaces/studio';
await loadStudioCatalogue('zh');

afterEach(cleanup);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,11 @@ vi.mock('../useMetadata', async (importOriginal) => {

import { DocPreview } from './DocPreview';
import { localeRefusal, patchAddLocale, patchRemoveLocale, resolvePlacements, toBookOptions } from './doc-draft';
// The designer rows this suite reads in zh live in `@object-ui/i18n`'s `studio`
// namespace, whose `zh` catalogue is fetched on demand (objectstack#25922).
// Resident before any case, so the zh rows below read synchronously.
import { loadStudioCatalogue } from '@object-ui/i18n/namespaces/studio';
await loadStudioCatalogue('zh');

const STUB_NS = 'doc-preview-test';

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,11 @@ vi.stubGlobal(

import { FlowPreview } from './FlowPreview';
import { t } from '../i18n';
// The designer rows this suite reads in zh live in `@object-ui/i18n`'s `studio`
// namespace, whose `zh` catalogue is fetched on demand (objectstack#25922).
// Resident before any case, so the zh rows below read synchronously.
import { loadStudioCatalogue } from '@object-ui/i18n/namespaces/studio';
await loadStudioCatalogue('zh');

afterEach(cleanup);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,13 @@
import { describe, it, expect, vi, afterEach } from 'vitest';
import { fetchFlowRuns, errorText, buildStepTree, regionLabel, groupChildren, parallelBranchIndex } from './FlowRunsPanel';
import type { StepTreeNode } from './FlowRunsPanel';
// The designer rows this suite reads in zh live in `@object-ui/i18n`'s `studio`
// namespace, whose `zh` catalogue is fetched on demand (objectstack#25922).
// Resident before any case: this file runs in the `unit` project, whose shared
// module graph would otherwise let it pass only when another file had loaded
// `zh` first.
import { loadStudioCatalogue } from '@object-ui/i18n/namespaces/studio';
await loadStudioCatalogue('zh');

const RUN = {
id: 'run-1',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,11 @@ import { render, screen, fireEvent, waitFor, cleanup } from '@testing-library/re
import { describe, it, expect, vi, beforeAll, beforeEach, afterEach } from 'vitest';
import { NodePalette, type PaletteItem } from './flow-canvas-parts';
import { readPaletteRecents } from './flowPaletteRecents';
// The designer rows this suite reads in zh live in `@object-ui/i18n`'s `studio`
// namespace, whose `zh` catalogue is fetched on demand (objectstack#25922).
// Resident before any case, so the zh rows below read synchronously.
import { loadStudioCatalogue } from '@object-ui/i18n/namespaces/studio';
await loadStudioCatalogue('zh');

beforeAll(() => {
// Radix Popover / cmdk probe pointer-capture APIs the test DOM lacks.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,13 @@ import { buildFlowProblems, deriveInvalidElements, edgeRouteKey } from './flow-p
import { tFormat } from '../i18n';
import { flowNodeDisplayName } from './flow-canvas-parts';
import type { FlowDesignerEdge } from './flow-canvas-layout';
// The designer rows this suite reads in zh live in `@object-ui/i18n`'s `studio`
// namespace, whose `zh` catalogue is fetched on demand (objectstack#25922).
// Resident before any case: this file runs in the `unit` project, whose shared
// module graph would otherwise let it pass only when another file had loaded
// `zh` first.
import { loadStudioCatalogue } from '@object-ui/i18n/namespaces/studio';
await loadStudioCatalogue('zh');

const NODES = [
{ id: 'start', type: 'start' },
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,11 @@ import { FlowPreview } from './FlowPreview';
import type { FlowProblem } from './flow-problems';
import { FlowNodeInspector } from '../inspectors/FlowNodeInspector';
import type { MetadataSelection } from '../preview-registry';
// The designer rows this suite reads in zh live in `@object-ui/i18n`'s `studio`
// namespace, whose `zh` catalogue is fetched on demand (objectstack#25922).
// Resident before any case, so the zh rows below read synchronously.
import { loadStudioCatalogue } from '@object-ui/i18n/namespaces/studio';
await loadStudioCatalogue('zh');

vi.stubGlobal(
'fetch',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,11 @@ import { ObjectListViewInspector, useObjectListViewDraft } from './ObjectListVie
import type { Surface } from './navSurface';
import { DraftTargetLabels, type DraftTargetLabel } from '../../hooks/useNavTargetLabel';
import { t } from '../metadata-admin/i18n';
// The designer rows this suite reads in zh live in `@object-ui/i18n`'s `studio`
// namespace, whose `zh` catalogue is fetched on demand (objectstack#25922).
// Resident before any case, so the zh rows below read synchronously.
import { loadStudioCatalogue } from '@object-ui/i18n/namespaces/studio';
await loadStudioCatalogue('zh');

function metadataOf(objects: unknown[]): MetadataContextValue {
return {
Expand Down
Loading
Loading