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
4 changes: 2 additions & 2 deletions packages/app-shell/src/views/ReportConfigPanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ import { useObjectTranslation } from '@object-ui/i18n';
import { X } from 'lucide-react';
import { ReportDefaultInspector } from './metadata-admin/inspectors/ReportDefaultInspector';
import { RuntimeDraftBar } from './RuntimeDraftBar';
import { detectLocale } from './metadata-admin/i18n';
import { useMetadataLocale } from './metadata-admin/i18n';

/** Field option shape the host (ReportView) already computes. */
interface AvailableField {
Expand Down Expand Up @@ -81,7 +81,7 @@ export function ReportConfigPanel({
onAfterChange,
}: ReportConfigPanelProps) {
const { t } = useObjectTranslation();
const locale = useMemo(() => detectLocale(), []);
const locale = useMetadataLocale();
// Unsaved-edits flag — gates Publish (mirrors studio's "save first").
const [dirty, setDirty] = useState(false);

Expand Down
4 changes: 2 additions & 2 deletions packages/app-shell/src/views/RuntimeDraftBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import {
readRuntimeDraft,
type RuntimeArtifactType,
} from './runtime-metadata-persistence';
import { detectLocale, t, tFormat } from './metadata-admin/i18n';
import { useMetadataLocale, t, tFormat } from './metadata-admin/i18n';

export interface RuntimeDraftBarProps {
/** Artifact type — the `:type` in `/meta/:type/:name`. */
Expand Down Expand Up @@ -61,7 +61,7 @@ export function RuntimeDraftBar({
onAfterChange,
savedSignal,
}: RuntimeDraftBarProps) {
const locale = detectLocale();
const locale = useMetadataLocale();
const [hasDraft, setHasDraft] = useState(false);
const [busy, setBusy] = useState(false);
// Track the `name` we've already resumed so reopening the same item doesn't
Expand Down
4 changes: 2 additions & 2 deletions packages/app-shell/src/views/ViewConfigPanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ import { useObjectTranslation } from '@object-ui/i18n';
import { ViewVariantInspector } from './metadata-admin/inspectors/ViewVariantInspector';
import { RuntimeDraftBar } from './RuntimeDraftBar';
import { isFormFamilyKey } from './metadata-admin/view-variant-model';
import { detectLocale } from './metadata-admin/i18n';
import { useMetadataLocale } from './metadata-admin/i18n';
import type { ObjectFieldInfo } from './metadata-admin/previews/useObjectFields';
import {
runtimeViewToInspectorDraft,
Expand Down Expand Up @@ -102,7 +102,7 @@ function mapObjectFields(objectDef: ViewConfigPanelProps['objectDef']): ObjectFi
export function ViewConfigPanel({ open, onClose, mode = 'edit', activeView, objectDef, onViewUpdate, onSave, onCreate, metadataClient, onAfterChange }: ViewConfigPanelProps) {
const { t } = useObjectTranslation();
const panelRef = useRef<HTMLDivElement>(null);
const locale = useMemo(() => detectLocale(), []);
const locale = useMetadataLocale();

// Provisional id for a create-mode view. A lazy useState initializer runs
// exactly once, keeping the impure `Date.now()` out of render; the backend
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ import { Button } from '@object-ui/components';
import { RecordPickerDialog } from '@object-ui/fields';
import { useAdapter } from '@object-ui/react';
import { Plus, X, Users, Loader2, AlertCircle } from 'lucide-react';
import { detectLocale } from './i18n';
import { useMetadataLocale } from './i18n';

export interface AssignedUsersSectionProps {
/** The permission set's machine name (e.g. `ai_seat`, `admin_full_access`). */
Expand All @@ -44,7 +44,7 @@ interface AssignedRow {

/** Minimal locale-aware copy (zh vs everything-else) — keeps the surface in the user's language. */
function useCopy() {
const zh = React.useMemo(() => detectLocale().toLowerCase().startsWith('zh'), []);
const zh = useMetadataLocale() === 'zh-CN';
return React.useMemo(
() =>
zh
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,13 @@ import {
useGlobalDiagnostics,
type MetadataDiagnosticsEntry,
} from './useMetadata';
import { t, tFormat, translateMetadataType, detectLocale } from './i18n';
import { t, tFormat, translateMetadataType, useMetadataLocale } from './i18n';

type Severity = 'error' | 'warning';

export function MetadataDiagnosticsPage() {
const client = useMetadataClient();
const locale = React.useMemo(() => detectLocale(), []);
const locale = useMetadataLocale();
const [severity, setSeverity] = React.useState<Severity>('error');
const { loading, error, summary, reload } = useGlobalDiagnostics(client, severity);
const { entries: typesEntries } = useMetadataTypes(client);
Expand Down
4 changes: 2 additions & 2 deletions packages/app-shell/src/views/metadata-admin/DirectoryPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ import {
translateMetadataDomain,
t,
tFormat,
detectLocale,
useMetadataLocale,
} from './i18n';
import { buildPackageScopeOptions } from './package-scope';

Expand Down Expand Up @@ -78,7 +78,7 @@ const HIDDEN_TYPES = new Set(['field', 'package']);
export function MetadataDirectoryPage() {
const client = useMetadataClient();
const { loading, error, entries } = useMetadataTypes(client);
const locale = React.useMemo(() => detectLocale(), []);
const locale = useMetadataLocale();

const [query, setQuery] = React.useState('');
const [domainFilter, setDomainFilter] = React.useState<string>('all');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import { Loader2, Save, AlertTriangle } from 'lucide-react';
import { Button } from '@object-ui/components';
import { SchemaForm, type SchemaFormIssue } from './SchemaForm';
import { useMetadataClient, useMetadataTypes } from './useMetadata';
import { detectLocale, t, tFormat, translateValidationMessage } from './i18n';
import { useMetadataLocale, t, tFormat, translateValidationMessage } from './i18n';

export interface EmbeddedItemEditorProps {
parentType: string;
Expand All @@ -47,7 +47,7 @@ export function EmbeddedItemEditor({
initialRaw,
onSaved,
}: EmbeddedItemEditorProps) {
const locale = React.useMemo(() => detectLocale(), []);
const locale = useMetadataLocale();
const client = useMetadataClient();
const { entries } = useMetadataTypes(client);
const subEntry = editAs ? entries.find((e) => e.type === editAs) : undefined;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
import React from 'react';
import { Skeleton } from '@object-ui/components';
import * as jsonc from 'jsonc-parser';
import { detectLocale, t } from './i18n';
import { useMetadataLocale, t } from './i18n';
import { useMonacoFallback } from './useMonacoFallback';

// Lazy: Monaco's React wrapper itself pulls in the editor core
Expand Down Expand Up @@ -76,7 +76,7 @@ export function JsonSourceEditor({
height = '60vh',
fallbackDelayMs = 4000,
}: JsonSourceEditorProps) {
const locale = React.useMemo(() => detectLocale(), []);
const locale = useMetadataLocale();
const [text, setText] = React.useState<string>(() => stringify(value));
const [parseError, setParseError] = React.useState<string | null>(null);
const lastCommittedRef = React.useRef<string>(text);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ import {
DialogDescription,
DialogFooter,
} from '@object-ui/components';
import { detectLocale, t, tFormat } from './i18n';
import { useMetadataLocale, t, tFormat } from './i18n';
import { SchemaForm, type SchemaFormIssue } from './SchemaForm';
import { getPackageSchema, getPackageForm } from './package-schema';

Expand Down Expand Up @@ -89,7 +89,7 @@ export function PackageFormDialog({
manifest?: ManifestRecord | null;
onSaved?: (result: PackageSaveResult) => void;
}) {
const locale = React.useMemo(() => detectLocale(), []);
const locale = useMetadataLocale();
const schema = React.useMemo(() => getPackageSchema(), []);
const form = React.useMemo(() => getPackageForm(locale), [locale]);

Expand Down
10 changes: 5 additions & 5 deletions packages/app-shell/src/views/metadata-admin/PackagesPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ import {
SheetTitle,
SheetDescription,
} from '@object-ui/components';
import { detectLocale, t, tFormat } from './i18n';
import { useMetadataLocale, t, tFormat } from './i18n';
import { PackageFormDialog } from './PackageFormDialog';

/* -------------------------------------------------------------------------- */
Expand Down Expand Up @@ -115,7 +115,7 @@ async function apiJson<T>(path: string, init?: RequestInit): Promise<T> {
/* -------------------------------------------------------------------------- */

function ScopeBadge({ scope }: { scope?: string }) {
const locale = React.useMemo(() => detectLocale(), []);
const locale = useMetadataLocale();
// Writability semantics, aligned with the builder (studio-design/packages-io):
// a SCOPE-LESS entry is a database base package (writable — authoring lives
// there), while `project` marks a read-only code package. Defaulting the
Expand All @@ -142,7 +142,7 @@ function ScopeBadge({ scope }: { scope?: string }) {
}

function StatusBadge({ pkg }: { pkg: InstalledPackage }) {
const locale = React.useMemo(() => detectLocale(), []);
const locale = useMetadataLocale();
const enabled = pkg.enabled !== false && pkg.status !== 'disabled';
return (
<Badge variant={enabled ? ('default' as any) : ('outline' as any)}>
Expand Down Expand Up @@ -238,7 +238,7 @@ export function PackageDetailSheet({
onOpenChange: (v: boolean) => void;
onChanged: () => void;
}) {
const locale = React.useMemo(() => detectLocale(), []);
const locale = useMetadataLocale();
const [busy, setBusy] = React.useState<string | null>(null);
const [msg, setMsg] = React.useState<{ kind: 'ok' | 'err'; text: string } | null>(null);
// ADR-0033 — pending DRAFT items bound to this package. AI-authored metadata
Expand Down Expand Up @@ -672,7 +672,7 @@ export function PackageDetailSheet({
/* -------------------------------------------------------------------------- */

export function PackagesPage() {
const locale = React.useMemo(() => detectLocale(), []);
const locale = useMetadataLocale();
const { pathname } = useLocation();
// App base = path up to (and excluding) `/component/...`, so links to
// `/apps/:app/metadata/...` work regardless of nesting.
Expand Down
4 changes: 2 additions & 2 deletions packages/app-shell/src/views/metadata-admin/PageShell.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import { Badge } from '@object-ui/components';
import { Button } from '@object-ui/components';
import { ChevronRight } from 'lucide-react';
import type { RichMetadataTypeEntry } from './useMetadata';
import { detectLocale, t, translateMetadataType, translateMetadataDomain } from './i18n';
import { useMetadataLocale, t, translateMetadataType, translateMetadataDomain } from './i18n';

export interface PageShellProps {
/** The type entry from `/meta/types` (or a synthesized stub). */
Expand All @@ -47,7 +47,7 @@ export function PageShell({
children,
}: PageShellProps) {
const type = entry?.type ?? '';
const locale = React.useMemo(() => detectLocale(), []);
const locale = useMetadataLocale();
// Prefer locale-table translation over server's English label.
const label = translateMetadataType(type, locale, entry?.label);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ import { CapabilityMultiSelectField, parseCapabilityNames } from '@object-ui/fie
import { PageShell } from './PageShell';
import { useMetadataClient, useMetadataTypes, type RichMetadataTypeEntry } from './useMetadata';
import { resolveResourceConfig } from './registry';
import { t as translate, detectLocale } from './i18n';
import { t as translate, useMetadataLocale } from './i18n';
import { PermissionAdvancedFacets } from './PermissionAdvancedFacets';
import {
mergePermissionSlice,
Expand Down Expand Up @@ -199,7 +199,7 @@ export function PermissionMatrixEditPage({ type, name, packageId, onDraftSaved,
// `readOnly` (read-only package in the Studio Access pillar). Either one
// must lock every authoring affordance below.
const writable = !!resolved.allowOrgOverride && !readOnly;
const locale = React.useMemo(() => detectLocale(), []);
const locale = useMetadataLocale();
const t = React.useCallback((k: string) => translate(k, locale), [locale]);
const OBJECT_ACTIONS = React.useMemo(() => getObjectActions(locale), [locale]);

Expand Down
4 changes: 2 additions & 2 deletions packages/app-shell/src/views/metadata-admin/QuickFind.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ import {
useMetadataTypes,
type RichMetadataTypeEntry,
} from './useMetadata';
import { detectLocale, t as tr, translateMetadataType } from './i18n';
import { useMetadataLocale, t as tr, translateMetadataType } from './i18n';

type ItemResult = {
kind: 'item';
Expand Down Expand Up @@ -73,7 +73,7 @@ export function MetadataQuickFind({ appSlug }: MetadataQuickFindProps = {}) {
const [items, setItems] = React.useState<ItemResult[] | null>(null);
const [itemsLoading, setItemsLoading] = React.useState(false);
const [activeIdx, setActiveIdx] = React.useState(0);
const locale = React.useMemo(() => detectLocale(), []);
const locale = useMetadataLocale();

// Global Cmd+Shift+M listener (avoids clashing with the existing
// CommandPalette which owns Cmd+K).
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ import { readFields } from './previews/object-fields-io';
import { useRegisterAssistantEditor, type AssistantEditorContext } from '../../assistant/assistantBus';
import { getMetadataInspector } from './inspector-registry';
import { getMetadataDefaultInspector } from './default-inspector-registry';
import { detectLocale, t, tFormat, translateValidationMessage } from './i18n';
import { useMetadataLocale, t, tFormat, translateValidationMessage } from './i18n';
import { JsonSourceEditor } from './JsonSourceEditor';
import { validateMetadataDraft, hasClientValidator } from './clientValidation';
import { describeIssuePath } from './issuePath';
Expand Down Expand Up @@ -275,7 +275,7 @@ function MetadataResourceEditPageImpl({
? config.createSchema
: (entry?.schema as Record<string, unknown> | undefined)) ??
(config.defaultSchema as Record<string, unknown> | undefined);
const locale = React.useMemo(() => detectLocale(), []);
const locale = useMetadataLocale();

const [layered, setLayered] = React.useState<MetadataLayered<any> | null>(null);
const identityField = config.identityField ?? 'name';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ import {
getMetadataResource,
resolveResourceConfig,
} from './registry';
import { t, tFormat, translateMetadataType, detectLocale } from './i18n';
import { t, tFormat, translateMetadataType, useMetadataLocale } from './i18n';
import { buildPackageScopeOptions } from './package-scope';

export interface MetadataResourceListPageProps {
Expand Down Expand Up @@ -335,7 +335,7 @@ function DefaultMetadataList({ type, appName }: { type: string; appName?: string
);

const columns = config.listColumns ?? defaultColumns(config.primaryKey ?? 'name');
const locale = detectLocale();
const locale = useMetadataLocale();
const typeLabel = translateMetadataType(type, locale, entry?.label ?? type);

// Localise default column labels — registered columns keep their
Expand Down
Loading
Loading