@object-ui/i18n 14.0.0 → 14.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,96 @@
1
1
  # @object-ui/i18n
2
2
 
3
+ ## 14.1.0
4
+
5
+ ### Patch Changes
6
+
7
+ - 82441e4: feat(console-ai): proactive AI usage indicator in the ChatDock (ADR-0057 #8)
8
+
9
+ Surfaces remaining AI headroom **before** a send hits the 429 wall, instead of
10
+ only learning the limit reactively.
11
+
12
+ - **AiUsageIndicator** — two meters (build + dataChat) as small progress rings in
13
+ the ChatDock header (desktop rail + mobile sheet). Near-full → an amber
14
+ "running low" hint and a popover with "resets tonight / next cycle" plus the
15
+ upgrade / top-up CTA (reusing the 429 deep-link). D5-safe: fractions and
16
+ qualitative words only, never a token number. Hides itself when the usage
17
+ endpoint is absent (older backend / OSS / no seat).
18
+ - **useAiUsage** — fetches the D5-safe per-meter fractions; refetches on the chat
19
+ engine's post-turn / 429 nudge and on tab re-focus; fails soft to nothing.
20
+ - **useObjectChat** emits `AI_USAGE_REFRESH_EVENT` on a rejected send (429) and on
21
+ the turn-finish edge so the ring updates right after the user's action.
22
+ - i18n: `console.ai.usage.*` in en + zh-CN.
23
+
24
+ Consumes the cloud `GET /api/v1/ai/usage` endpoint (objectstack-ai/cloud#824).
25
+
26
+ - 2efa9fd: Detail-page UX follow-ups from the ADR-0085 PR4 real-backend browser pass (framework#2548):
27
+
28
+ - **Highlight strip no longer repeats the record title.** A declared
29
+ `highlightFields` list containing the title field rendered it as the first
30
+ chip — truncated — directly under the identical page H1. `deriveHighlightFields`
31
+ now resolves the title (`primaryField` / `nameField` / deprecated
32
+ `displayNameField`, else the conventional display-field names) via the new
33
+ exported `resolveTitleField` and filters it from declared lists before the
34
+ 4-chip cap, matching what the heuristic branch always did. app-shell's
35
+ `RecordDetailView` synthParts (which pre-computes the list and bypasses the
36
+ derivation) applies the same filter.
37
+ - **Per-field currency reaches the renderers.** The spec channel
38
+ (`currencyConfig.defaultCurrency`) was dropped by the highlight-strip and
39
+ detail-section field enrichment, so a spec-authored currency field could
40
+ never show its symbol ("25,000,000" instead of "$25,000,000");
41
+ `resolveFieldCurrency` reads it second after the designer-only bare
42
+ `currency` key.
43
+ - **app-shell approvals fetches send the Bearer token.** The header badge
44
+ poll, home-inbox count, and record-page approvals panel were cookie-only
45
+ (new shared `bearerAuthHeaders()` util) — same split-origin failure mode as
46
+ the console `approvalsApi` fix below.
47
+ - **`fieldGroups[].icon` / `description` reach detail pages.** The shared
48
+ derivation (ADR-0085 §5) already passed them through; the detail synth
49
+ dropped them. Sections now carry both, and `DetailSection` renders a real
50
+ Lucide icon for identifier-shaped names (emoji/text values keep the
51
+ historical text rendering).
52
+ - **Record meta footer stops dangling without an actor.** Seeded/system rows
53
+ with `created_by: null` rendered "Created by · 10m ago"; the footer now
54
+ falls back to actor-less labels ("Created / Updated"), with new i18n keys in
55
+ all six locales (and the zh `createdBy`/`updatedBy` mistranslation fixed:
56
+ 创建人/更新人, not 创建于/更新于).
57
+ - **Select badges ellipsize instead of clipping mid-glyph.** In bounded
58
+ containers (highlight-strip columns, grid cells) an overlong option label
59
+ used to be cut at the container edge ("Technolog…"); badges now shrink with
60
+ an inner truncate and expose the full label as a hover title. The highlight
61
+ strip's hover title also prefers the option label over the raw stored value.
62
+
63
+ Console app (unversioned): `approvalsApi` now sends the stored Bearer token
64
+ like every other console call — cookie-only auth silently lost the approvals
65
+ surface on split-origin deployments where the SameSite cookie doesn't flow.
66
+
67
+ - e628d1f: Dashboard-level filters follow-ups (#2578, framework#2501):
68
+
69
+ - **i18n**: the `DashboardFilterBar` strings now ship as real locale entries —
70
+ `dashboard.filters.*` (bar label, "All time", "Custom…", "All", "Reset",
71
+ and the 13 date-range preset labels) added to `en` and `zh`. Previously the
72
+ bar always rendered the `useSafeTranslate` English fallbacks.
73
+ - **types**: `GlobalFilterSchema.name` and `DashboardWidgetSchema.filterBindings`
74
+ landed in `@objectstack/spec` (framework#2501), so the local type
75
+ annotations flip from "Pending alignment" to "Aligned" — no shape changes.
76
+
77
+ Also adds five schema-catalog examples (`plugin-dashboard/filtered-dashboard-*`:
78
+ dynamic `optionsFrom` options, text/number/lookup filter types, dataset +
79
+ inline widget mix, `targetWidgets` allow-list, date presets + custom range)
80
+ and a new "Dashboard-Level Filters" guide page covering the full tutorial,
81
+ `page.*` expression usage, and known limitations with workarounds.
82
+
83
+ - 23d65c3: fix(i18n): `createSafeTranslation` / `useSafeTranslate` no longer wrap the
84
+ translation hook in try/catch — the last known rules-of-hooks violation of
85
+ the class fixed in objectui#2595/#2596 (a throw after the hook ran would
86
+ desync hook order on the next render; the factory closure just escaped the
87
+ static lint). `useObjectTranslation` is provider-safe, and the actual
88
+ fallback behavior is unchanged: the testKey probe (createSafeTranslation)
89
+ and per-key `t(key) === key` detection (useSafeTranslate) still return the
90
+ English defaults when translations aren't configured. The fallback `t` is
91
+ now a stable per-factory reference, so downstream memo deps stop
92
+ invalidating every render in the no-translations case.
93
+
3
94
  ## 14.0.0
4
95
 
5
96
  ### Patch Changes
@@ -105,6 +105,9 @@ declare const ar: {
105
105
  deleteSuccess: string;
106
106
  };
107
107
  fields: {
108
+ relativeDate: {
109
+ overdue: string;
110
+ };
108
111
  richText: {
109
112
  format: string;
110
113
  basicEditorHint: string;
@@ -105,6 +105,9 @@ const ar = {
105
105
  deleteSuccess: "تم حذف {{object}}",
106
106
  },
107
107
  fields: {
108
+ relativeDate: {
109
+ overdue: "متأخر {{count}} يوم",
110
+ },
108
111
  richText: {
109
112
  format: "التنسيق: {{format}}",
110
113
  basicEditorHint: "محرر النص الغني (أساسي)",
@@ -105,6 +105,9 @@ declare const de: {
105
105
  deleteSuccess: string;
106
106
  };
107
107
  fields: {
108
+ relativeDate: {
109
+ overdue: string;
110
+ };
108
111
  richText: {
109
112
  format: string;
110
113
  basicEditorHint: string;
@@ -510,6 +513,8 @@ declare const de: {
510
513
  highlightFields: string;
511
514
  createdBy: string;
512
515
  updatedBy: string;
516
+ created: string;
517
+ updated: string;
513
518
  showEmptyRelated_one: string;
514
519
  showEmptyRelated_other: string;
515
520
  copyEmail: string;
@@ -105,6 +105,9 @@ const de = {
105
105
  deleteSuccess: "{{object}} erfolgreich gelöscht",
106
106
  },
107
107
  fields: {
108
+ relativeDate: {
109
+ overdue: "{{count}} T. überfällig",
110
+ },
108
111
  richText: {
109
112
  format: "Format: {{format}}",
110
113
  basicEditorHint: "Rich-Text-Editor (einfach)",
@@ -510,6 +513,8 @@ const de = {
510
513
  highlightFields: "Schlüsselfelder",
511
514
  createdBy: "Erstellt von",
512
515
  updatedBy: "Aktualisiert von",
516
+ created: "Erstellt",
517
+ updated: "Aktualisiert",
513
518
  showEmptyRelated_one: "+ {{count}} leer",
514
519
  showEmptyRelated_other: "+ {{count}} leer",
515
520
  copyEmail: "E-Mail kopieren",
@@ -112,6 +112,9 @@ declare const en: {
112
112
  readonly deleteSuccess: "{{object}} deleted successfully";
113
113
  };
114
114
  readonly fields: {
115
+ readonly relativeDate: {
116
+ readonly overdue: "Overdue {{count}}d";
117
+ };
115
118
  readonly richText: {
116
119
  readonly format: "Format: {{format}}";
117
120
  readonly basicEditorHint: "Rich text editor (basic)";
@@ -608,6 +611,8 @@ declare const en: {
608
611
  readonly unknownUser: "Unknown";
609
612
  readonly createdBy: "Created by";
610
613
  readonly updatedBy: "Updated by";
614
+ readonly created: "Created";
615
+ readonly updated: "Updated";
611
616
  readonly dropFilesToUpload: "Drop files here or click to upload";
612
617
  readonly attachmentCount: "{{count}} attachment";
613
618
  readonly attachmentCountPlural: "{{count}} attachments";
@@ -893,6 +898,29 @@ declare const en: {
893
898
  readonly vsYesterday: "vs yesterday";
894
899
  readonly vsPreviousPeriod: "vs previous period";
895
900
  };
901
+ readonly filters: {
902
+ readonly label: "Dashboard filters";
903
+ readonly dateRange: "Date range";
904
+ readonly allTime: "All time";
905
+ readonly custom: "Custom…";
906
+ readonly all: "All";
907
+ readonly reset: "Reset";
908
+ readonly range: {
909
+ readonly today: "Today";
910
+ readonly yesterday: "Yesterday";
911
+ readonly this_week: "This week";
912
+ readonly last_week: "Last week";
913
+ readonly this_month: "This month";
914
+ readonly last_month: "Last month";
915
+ readonly this_quarter: "This quarter";
916
+ readonly last_quarter: "Last quarter";
917
+ readonly this_year: "This year";
918
+ readonly last_year: "Last year";
919
+ readonly last_7_days: "Last 7 days";
920
+ readonly last_30_days: "Last 30 days";
921
+ readonly last_90_days: "Last 90 days";
922
+ };
923
+ };
896
924
  };
897
925
  readonly configPanel: {
898
926
  readonly save: "Save";
@@ -1177,6 +1205,19 @@ declare const en: {
1177
1205
  readonly createApp: "Create New App";
1178
1206
  };
1179
1207
  readonly ai: {
1208
+ readonly usage: {
1209
+ readonly title: "AI usage";
1210
+ readonly meterBuild: "Build";
1211
+ readonly meterAsk: "Ask";
1212
+ readonly statusOk: "Plenty left";
1213
+ readonly statusLow: "Running low";
1214
+ readonly statusFull: "Limit reached";
1215
+ readonly resetsDaily: "Resets tonight";
1216
+ readonly resetsMonthly: "Resets next cycle";
1217
+ readonly ctaUpgrade: "Upgrade to keep going";
1218
+ readonly ctaTopUp: "Add credits to continue";
1219
+ readonly ariaLabel: "AI usage: {{status}}";
1220
+ };
1180
1221
  readonly workspaceTitle: "AI Workspace";
1181
1222
  readonly workspaceSubtitle: "Ask, inspect, and resume conversations";
1182
1223
  readonly openChats: "Open chats";
@@ -1203,6 +1244,8 @@ declare const en: {
1203
1244
  readonly sendFailedGeneric: "Couldn't send your message. It's kept below — please try again.";
1204
1245
  readonly askAgent: "Ask {{agent}}...";
1205
1246
  readonly assistant: "Assistant";
1247
+ readonly liveCanvas: "Live preview — {{app}} (draft)";
1248
+ readonly liveCanvasUnlisted: "Live app — {{app}} (unlisted until published)";
1206
1249
  readonly loadingAgents: "Loading agents...";
1207
1250
  readonly askAnything: "Ask anything...";
1208
1251
  readonly emptyTitle: "Start a conversation";
@@ -1218,6 +1261,11 @@ declare const en: {
1218
1261
  readonly title: "Ask your data";
1219
1262
  readonly description: "Ask questions about your records — counts, lists, and summaries across the data you can access.";
1220
1263
  };
1264
+ readonly editApp: {
1265
+ readonly title: "Editing “{{app}}”";
1266
+ readonly titleGeneric: "Edit this app";
1267
+ readonly description: "What would you like to change? I’ll modify this app in place — add a field, object, view or automation, or adjust what’s already there.";
1268
+ };
1221
1269
  };
1222
1270
  readonly clearConversation: "Clear";
1223
1271
  readonly sendHint: "to send";
@@ -1283,6 +1331,12 @@ declare const en: {
1283
1331
  readonly availableObjects: "List the available data objects.";
1284
1332
  readonly recentActivity: "Summarize my recent activity.";
1285
1333
  };
1334
+ readonly editApp: {
1335
+ readonly addField: "Add a field to one of the objects.";
1336
+ readonly addObject: "Add a new object and relate it to an existing one.";
1337
+ readonly addDashboard: "Add a dashboard for the key metrics.";
1338
+ readonly addAutomation: "Add an automation — an approval, a status flow, or a notification.";
1339
+ };
1286
1340
  };
1287
1341
  };
1288
1342
  readonly errors: {
@@ -112,6 +112,9 @@ const en = {
112
112
  deleteSuccess: '{{object}} deleted successfully',
113
113
  },
114
114
  fields: {
115
+ relativeDate: {
116
+ overdue: 'Overdue {{count}}d',
117
+ },
115
118
  richText: {
116
119
  format: 'Format: {{format}}',
117
120
  basicEditorHint: 'Rich text editor (basic)',
@@ -609,9 +612,13 @@ const en = {
609
612
  // Activity feed actors
610
613
  systemActor: 'System',
611
614
  unknownUser: 'Unknown',
612
- // Record meta footer (audit provenance)
615
+ // Record meta footer (audit provenance). `created`/`updated` are the
616
+ // actor-less variants — "Created by · 5m ago" dangles when created_by
617
+ // is null (system/seeded rows), so the footer falls back to these.
613
618
  createdBy: 'Created by',
614
619
  updatedBy: 'Updated by',
620
+ created: 'Created',
621
+ updated: 'Updated',
615
622
  // Attachments
616
623
  dropFilesToUpload: 'Drop files here or click to upload',
617
624
  attachmentCount: '{{count}} attachment',
@@ -906,6 +913,29 @@ const en = {
906
913
  vsYesterday: 'vs yesterday',
907
914
  vsPreviousPeriod: 'vs previous period',
908
915
  },
916
+ filters: {
917
+ label: 'Dashboard filters',
918
+ dateRange: 'Date range',
919
+ allTime: 'All time',
920
+ custom: 'Custom…',
921
+ all: 'All',
922
+ reset: 'Reset',
923
+ range: {
924
+ today: 'Today',
925
+ yesterday: 'Yesterday',
926
+ this_week: 'This week',
927
+ last_week: 'Last week',
928
+ this_month: 'This month',
929
+ last_month: 'Last month',
930
+ this_quarter: 'This quarter',
931
+ last_quarter: 'Last quarter',
932
+ this_year: 'This year',
933
+ last_year: 'Last year',
934
+ last_7_days: 'Last 7 days',
935
+ last_30_days: 'Last 30 days',
936
+ last_90_days: 'Last 90 days',
937
+ },
938
+ },
909
939
  },
910
940
  configPanel: {
911
941
  save: 'Save',
@@ -1190,6 +1220,19 @@ const en = {
1190
1220
  createApp: 'Create New App',
1191
1221
  },
1192
1222
  ai: {
1223
+ usage: {
1224
+ title: 'AI usage',
1225
+ meterBuild: 'Build',
1226
+ meterAsk: 'Ask',
1227
+ statusOk: 'Plenty left',
1228
+ statusLow: 'Running low',
1229
+ statusFull: 'Limit reached',
1230
+ resetsDaily: 'Resets tonight',
1231
+ resetsMonthly: 'Resets next cycle',
1232
+ ctaUpgrade: 'Upgrade to keep going',
1233
+ ctaTopUp: 'Add credits to continue',
1234
+ ariaLabel: 'AI usage: {{status}}',
1235
+ },
1193
1236
  workspaceTitle: 'AI Workspace',
1194
1237
  workspaceSubtitle: 'Ask, inspect, and resume conversations',
1195
1238
  openChats: 'Open chats',
@@ -1216,6 +1259,8 @@ const en = {
1216
1259
  sendFailedGeneric: "Couldn't send your message. It's kept below — please try again.",
1217
1260
  askAgent: 'Ask {{agent}}...',
1218
1261
  assistant: 'Assistant',
1262
+ liveCanvas: 'Live preview — {{app}} (draft)',
1263
+ liveCanvasUnlisted: 'Live app — {{app}} (unlisted until published)',
1219
1264
  loadingAgents: 'Loading agents...',
1220
1265
  askAnything: 'Ask anything...',
1221
1266
  emptyTitle: 'Start a conversation',
@@ -1231,6 +1276,11 @@ const en = {
1231
1276
  title: 'Ask your data',
1232
1277
  description: 'Ask questions about your records — counts, lists, and summaries across the data you can access.',
1233
1278
  },
1279
+ editApp: {
1280
+ title: 'Editing “{{app}}”',
1281
+ titleGeneric: 'Edit this app',
1282
+ description: 'What would you like to change? I’ll modify this app in place — add a field, object, view or automation, or adjust what’s already there.',
1283
+ },
1234
1284
  },
1235
1285
  clearConversation: 'Clear',
1236
1286
  sendHint: 'to send',
@@ -1299,6 +1349,12 @@ const en = {
1299
1349
  availableObjects: 'List the available data objects.',
1300
1350
  recentActivity: 'Summarize my recent activity.',
1301
1351
  },
1352
+ editApp: {
1353
+ addField: 'Add a field to one of the objects.',
1354
+ addObject: 'Add a new object and relate it to an existing one.',
1355
+ addDashboard: 'Add a dashboard for the key metrics.',
1356
+ addAutomation: 'Add an automation — an approval, a status flow, or a notification.',
1357
+ },
1302
1358
  },
1303
1359
  },
1304
1360
  errors: {
@@ -105,6 +105,9 @@ declare const es: {
105
105
  deleteSuccess: string;
106
106
  };
107
107
  fields: {
108
+ relativeDate: {
109
+ overdue: string;
110
+ };
108
111
  richText: {
109
112
  format: string;
110
113
  basicEditorHint: string;
@@ -510,6 +513,8 @@ declare const es: {
510
513
  highlightFields: string;
511
514
  createdBy: string;
512
515
  updatedBy: string;
516
+ created: string;
517
+ updated: string;
513
518
  showEmptyRelated_one: string;
514
519
  showEmptyRelated_other: string;
515
520
  copyEmail: string;
@@ -105,6 +105,9 @@ const es = {
105
105
  deleteSuccess: "{{object}} eliminado",
106
106
  },
107
107
  fields: {
108
+ relativeDate: {
109
+ overdue: "Atrasado {{count}} d",
110
+ },
108
111
  richText: {
109
112
  format: "Formato: {{format}}",
110
113
  basicEditorHint: "Editor de texto enriquecido (básico)",
@@ -510,6 +513,8 @@ const es = {
510
513
  highlightFields: "Campos clave",
511
514
  createdBy: "Creado por",
512
515
  updatedBy: "Actualizado por",
516
+ created: "Creado",
517
+ updated: "Actualizado",
513
518
  showEmptyRelated_one: "+ {{count}} vacío",
514
519
  showEmptyRelated_other: "+ {{count}} vacíos",
515
520
  copyEmail: "Copiar correo",
@@ -105,6 +105,9 @@ declare const fr: {
105
105
  deleteSuccess: string;
106
106
  };
107
107
  fields: {
108
+ relativeDate: {
109
+ overdue: string;
110
+ };
108
111
  richText: {
109
112
  format: string;
110
113
  basicEditorHint: string;
@@ -105,6 +105,9 @@ const fr = {
105
105
  deleteSuccess: "{{object}} supprimé",
106
106
  },
107
107
  fields: {
108
+ relativeDate: {
109
+ overdue: "En retard de {{count}} j",
110
+ },
108
111
  richText: {
109
112
  format: "Format : {{format}}",
110
113
  basicEditorHint: "Éditeur de texte enrichi (basique)",
@@ -124,6 +124,9 @@ export declare const builtInLocales: {
124
124
  readonly deleteSuccess: "{{object}} deleted successfully";
125
125
  };
126
126
  readonly fields: {
127
+ readonly relativeDate: {
128
+ readonly overdue: "Overdue {{count}}d";
129
+ };
127
130
  readonly richText: {
128
131
  readonly format: "Format: {{format}}";
129
132
  readonly basicEditorHint: "Rich text editor (basic)";
@@ -620,6 +623,8 @@ export declare const builtInLocales: {
620
623
  readonly unknownUser: "Unknown";
621
624
  readonly createdBy: "Created by";
622
625
  readonly updatedBy: "Updated by";
626
+ readonly created: "Created";
627
+ readonly updated: "Updated";
623
628
  readonly dropFilesToUpload: "Drop files here or click to upload";
624
629
  readonly attachmentCount: "{{count}} attachment";
625
630
  readonly attachmentCountPlural: "{{count}} attachments";
@@ -905,6 +910,29 @@ export declare const builtInLocales: {
905
910
  readonly vsYesterday: "vs yesterday";
906
911
  readonly vsPreviousPeriod: "vs previous period";
907
912
  };
913
+ readonly filters: {
914
+ readonly label: "Dashboard filters";
915
+ readonly dateRange: "Date range";
916
+ readonly allTime: "All time";
917
+ readonly custom: "Custom…";
918
+ readonly all: "All";
919
+ readonly reset: "Reset";
920
+ readonly range: {
921
+ readonly today: "Today";
922
+ readonly yesterday: "Yesterday";
923
+ readonly this_week: "This week";
924
+ readonly last_week: "Last week";
925
+ readonly this_month: "This month";
926
+ readonly last_month: "Last month";
927
+ readonly this_quarter: "This quarter";
928
+ readonly last_quarter: "Last quarter";
929
+ readonly this_year: "This year";
930
+ readonly last_year: "Last year";
931
+ readonly last_7_days: "Last 7 days";
932
+ readonly last_30_days: "Last 30 days";
933
+ readonly last_90_days: "Last 90 days";
934
+ };
935
+ };
908
936
  };
909
937
  readonly configPanel: {
910
938
  readonly save: "Save";
@@ -1189,6 +1217,19 @@ export declare const builtInLocales: {
1189
1217
  readonly createApp: "Create New App";
1190
1218
  };
1191
1219
  readonly ai: {
1220
+ readonly usage: {
1221
+ readonly title: "AI usage";
1222
+ readonly meterBuild: "Build";
1223
+ readonly meterAsk: "Ask";
1224
+ readonly statusOk: "Plenty left";
1225
+ readonly statusLow: "Running low";
1226
+ readonly statusFull: "Limit reached";
1227
+ readonly resetsDaily: "Resets tonight";
1228
+ readonly resetsMonthly: "Resets next cycle";
1229
+ readonly ctaUpgrade: "Upgrade to keep going";
1230
+ readonly ctaTopUp: "Add credits to continue";
1231
+ readonly ariaLabel: "AI usage: {{status}}";
1232
+ };
1192
1233
  readonly workspaceTitle: "AI Workspace";
1193
1234
  readonly workspaceSubtitle: "Ask, inspect, and resume conversations";
1194
1235
  readonly openChats: "Open chats";
@@ -1215,6 +1256,8 @@ export declare const builtInLocales: {
1215
1256
  readonly sendFailedGeneric: "Couldn't send your message. It's kept below — please try again.";
1216
1257
  readonly askAgent: "Ask {{agent}}...";
1217
1258
  readonly assistant: "Assistant";
1259
+ readonly liveCanvas: "Live preview — {{app}} (draft)";
1260
+ readonly liveCanvasUnlisted: "Live app — {{app}} (unlisted until published)";
1218
1261
  readonly loadingAgents: "Loading agents...";
1219
1262
  readonly askAnything: "Ask anything...";
1220
1263
  readonly emptyTitle: "Start a conversation";
@@ -1230,6 +1273,11 @@ export declare const builtInLocales: {
1230
1273
  readonly title: "Ask your data";
1231
1274
  readonly description: "Ask questions about your records — counts, lists, and summaries across the data you can access.";
1232
1275
  };
1276
+ readonly editApp: {
1277
+ readonly title: "Editing “{{app}}”";
1278
+ readonly titleGeneric: "Edit this app";
1279
+ readonly description: "What would you like to change? I’ll modify this app in place — add a field, object, view or automation, or adjust what’s already there.";
1280
+ };
1233
1281
  };
1234
1282
  readonly clearConversation: "Clear";
1235
1283
  readonly sendHint: "to send";
@@ -1295,6 +1343,12 @@ export declare const builtInLocales: {
1295
1343
  readonly availableObjects: "List the available data objects.";
1296
1344
  readonly recentActivity: "Summarize my recent activity.";
1297
1345
  };
1346
+ readonly editApp: {
1347
+ readonly addField: "Add a field to one of the objects.";
1348
+ readonly addObject: "Add a new object and relate it to an existing one.";
1349
+ readonly addDashboard: "Add a dashboard for the key metrics.";
1350
+ readonly addAutomation: "Add an automation — an approval, a status flow, or a notification.";
1351
+ };
1298
1352
  };
1299
1353
  };
1300
1354
  readonly errors: {
@@ -2651,6 +2705,9 @@ export declare const builtInLocales: {
2651
2705
  readonly deleteSuccess: "{{object}}删除成功";
2652
2706
  };
2653
2707
  readonly fields: {
2708
+ readonly relativeDate: {
2709
+ readonly overdue: "逾期 {{count}} 天";
2710
+ };
2654
2711
  readonly richText: {
2655
2712
  readonly format: "格式: {{format}}";
2656
2713
  readonly basicEditorHint: "富文本编辑器(基础)";
@@ -3217,8 +3274,10 @@ export declare const builtInLocales: {
3217
3274
  readonly daysAgo: "{{count}}天前";
3218
3275
  readonly systemActor: "系统";
3219
3276
  readonly unknownUser: "未知用户";
3220
- readonly createdBy: "创建于";
3221
- readonly updatedBy: "更新于";
3277
+ readonly createdBy: "创建人";
3278
+ readonly updatedBy: "更新人";
3279
+ readonly created: "创建于";
3280
+ readonly updated: "更新于";
3222
3281
  readonly dropFilesToUpload: "拖拽文件到此处或点击上传";
3223
3282
  readonly attachmentCount: "{{count}} 个附件";
3224
3283
  readonly attachmentCountPlural: "{{count}} 个附件";
@@ -3500,6 +3559,29 @@ export declare const builtInLocales: {
3500
3559
  readonly vsYesterday: "较昨日";
3501
3560
  readonly vsPreviousPeriod: "较上期";
3502
3561
  };
3562
+ readonly filters: {
3563
+ readonly label: "仪表盘过滤器";
3564
+ readonly dateRange: "日期范围";
3565
+ readonly allTime: "全部时间";
3566
+ readonly custom: "自定义…";
3567
+ readonly all: "全部";
3568
+ readonly reset: "重置";
3569
+ readonly range: {
3570
+ readonly today: "今天";
3571
+ readonly yesterday: "昨天";
3572
+ readonly this_week: "本周";
3573
+ readonly last_week: "上周";
3574
+ readonly this_month: "本月";
3575
+ readonly last_month: "上月";
3576
+ readonly this_quarter: "本季度";
3577
+ readonly last_quarter: "上季度";
3578
+ readonly this_year: "今年";
3579
+ readonly last_year: "去年";
3580
+ readonly last_7_days: "近 7 天";
3581
+ readonly last_30_days: "近 30 天";
3582
+ readonly last_90_days: "近 90 天";
3583
+ };
3584
+ };
3503
3585
  };
3504
3586
  readonly configPanel: {
3505
3587
  readonly save: "保存";
@@ -3783,6 +3865,19 @@ export declare const builtInLocales: {
3783
3865
  readonly createApp: "创建新应用";
3784
3866
  };
3785
3867
  readonly ai: {
3868
+ readonly usage: {
3869
+ readonly title: "AI 用量";
3870
+ readonly meterBuild: "AI 搭建";
3871
+ readonly meterAsk: "数据问询";
3872
+ readonly statusOk: "额度充足";
3873
+ readonly statusLow: "即将用完";
3874
+ readonly statusFull: "额度已用完";
3875
+ readonly resetsDaily: "今晚重置";
3876
+ readonly resetsMonthly: "下个周期重置";
3877
+ readonly ctaUpgrade: "升级以继续使用";
3878
+ readonly ctaTopUp: "购买额度包以继续";
3879
+ readonly ariaLabel: "AI 用量:{{status}}";
3880
+ };
3786
3881
  readonly workspaceTitle: "AI 工作区";
3787
3882
  readonly workspaceSubtitle: "提问、查看并继续历史对话";
3788
3883
  readonly openChats: "打开对话列表";
@@ -3809,6 +3904,8 @@ export declare const builtInLocales: {
3809
3904
  readonly sendFailedGeneric: "消息发送失败,请重试。你的消息已保留在输入框中。";
3810
3905
  readonly askAgent: "向 {{agent}} 提问...";
3811
3906
  readonly assistant: "助手";
3907
+ readonly liveCanvas: "草稿预览 · {{app}}";
3908
+ readonly liveCanvasUnlisted: "运行预览 · {{app}}(未发布 · 仅自己可见)";
3812
3909
  readonly loadingAgents: "正在加载助手...";
3813
3910
  readonly askAnything: "输入你的问题...";
3814
3911
  readonly emptyTitle: "开始对话";
@@ -3824,6 +3921,11 @@ export declare const builtInLocales: {
3824
3921
  readonly title: "向你的数据提问";
3825
3922
  readonly description: "针对你的记录提问 —— 在你有权访问的数据范围内进行计数、列举和汇总。";
3826
3923
  };
3924
+ readonly editApp: {
3925
+ readonly title: "正在编辑「{{app}}」";
3926
+ readonly titleGeneric: "编辑此应用";
3927
+ readonly description: "想改点什么?我会就地修改这个应用 —— 加字段、对象、视图或自动化,或调整已有内容。";
3928
+ };
3827
3929
  };
3828
3930
  readonly clearConversation: "清空";
3829
3931
  readonly sendHint: "发送";
@@ -3887,6 +3989,12 @@ export declare const builtInLocales: {
3887
3989
  readonly availableObjects: "列出可用的数据对象。";
3888
3990
  readonly recentActivity: "总结我的最近动态。";
3889
3991
  };
3992
+ readonly editApp: {
3993
+ readonly addField: "给某个对象加一个字段。";
3994
+ readonly addObject: "新增一个对象,并关联到已有对象。";
3995
+ readonly addDashboard: "加一个展示关键指标的仪表盘。";
3996
+ readonly addAutomation: "加一个自动化 —— 审批、状态流转或通知。";
3997
+ };
3890
3998
  };
3891
3999
  };
3892
4000
  readonly errors: {
@@ -5252,6 +5360,9 @@ export declare const builtInLocales: {
5252
5360
  deleteSuccess: string;
5253
5361
  };
5254
5362
  fields: {
5363
+ relativeDate: {
5364
+ overdue: string;
5365
+ };
5255
5366
  richText: {
5256
5367
  format: string;
5257
5368
  basicEditorHint: string;
@@ -5657,6 +5768,8 @@ export declare const builtInLocales: {
5657
5768
  deleteRowTitle: string;
5658
5769
  createdBy: string;
5659
5770
  updatedBy: string;
5771
+ created: string;
5772
+ updated: string;
5660
5773
  showEmptyRelated_one: string;
5661
5774
  showEmptyRelated_other: string;
5662
5775
  copyEmail: string;
@@ -7404,6 +7517,9 @@ export declare const builtInLocales: {
7404
7517
  deleteSuccess: string;
7405
7518
  };
7406
7519
  fields: {
7520
+ relativeDate: {
7521
+ overdue: string;
7522
+ };
7407
7523
  richText: {
7408
7524
  format: string;
7409
7525
  basicEditorHint: string;
@@ -7809,6 +7925,8 @@ export declare const builtInLocales: {
7809
7925
  highlightFields: string;
7810
7926
  createdBy: string;
7811
7927
  updatedBy: string;
7928
+ created: string;
7929
+ updated: string;
7812
7930
  showEmptyRelated_one: string;
7813
7931
  showEmptyRelated_other: string;
7814
7932
  copyEmail: string;
@@ -9556,6 +9674,9 @@ export declare const builtInLocales: {
9556
9674
  deleteSuccess: string;
9557
9675
  };
9558
9676
  fields: {
9677
+ relativeDate: {
9678
+ overdue: string;
9679
+ };
9559
9680
  richText: {
9560
9681
  format: string;
9561
9682
  basicEditorHint: string;
@@ -9961,6 +10082,8 @@ export declare const builtInLocales: {
9961
10082
  highlightFields: string;
9962
10083
  createdBy: string;
9963
10084
  updatedBy: string;
10085
+ created: string;
10086
+ updated: string;
9964
10087
  showEmptyRelated_one: string;
9965
10088
  showEmptyRelated_other: string;
9966
10089
  copyEmail: string;
@@ -11708,6 +11831,9 @@ export declare const builtInLocales: {
11708
11831
  deleteSuccess: string;
11709
11832
  };
11710
11833
  fields: {
11834
+ relativeDate: {
11835
+ overdue: string;
11836
+ };
11711
11837
  richText: {
11712
11838
  format: string;
11713
11839
  basicEditorHint: string;
@@ -13860,6 +13986,9 @@ export declare const builtInLocales: {
13860
13986
  deleteSuccess: string;
13861
13987
  };
13862
13988
  fields: {
13989
+ relativeDate: {
13990
+ overdue: string;
13991
+ };
13863
13992
  richText: {
13864
13993
  format: string;
13865
13994
  basicEditorHint: string;
@@ -14265,6 +14394,8 @@ export declare const builtInLocales: {
14265
14394
  highlightFields: string;
14266
14395
  createdBy: string;
14267
14396
  updatedBy: string;
14397
+ created: string;
14398
+ updated: string;
14268
14399
  showEmptyRelated_one: string;
14269
14400
  showEmptyRelated_other: string;
14270
14401
  copyEmail: string;
@@ -16012,6 +16143,9 @@ export declare const builtInLocales: {
16012
16143
  deleteSuccess: string;
16013
16144
  };
16014
16145
  fields: {
16146
+ relativeDate: {
16147
+ overdue: string;
16148
+ };
16015
16149
  richText: {
16016
16150
  format: string;
16017
16151
  basicEditorHint: string;
@@ -18164,6 +18298,9 @@ export declare const builtInLocales: {
18164
18298
  deleteSuccess: string;
18165
18299
  };
18166
18300
  fields: {
18301
+ relativeDate: {
18302
+ overdue: string;
18303
+ };
18167
18304
  richText: {
18168
18305
  format: string;
18169
18306
  basicEditorHint: string;
@@ -20316,6 +20453,9 @@ export declare const builtInLocales: {
20316
20453
  deleteSuccess: string;
20317
20454
  };
20318
20455
  fields: {
20456
+ relativeDate: {
20457
+ overdue: string;
20458
+ };
20319
20459
  richText: {
20320
20460
  format: string;
20321
20461
  basicEditorHint: string;
@@ -105,6 +105,9 @@ declare const ja: {
105
105
  deleteSuccess: string;
106
106
  };
107
107
  fields: {
108
+ relativeDate: {
109
+ overdue: string;
110
+ };
108
111
  richText: {
109
112
  format: string;
110
113
  basicEditorHint: string;
@@ -510,6 +513,8 @@ declare const ja: {
510
513
  deleteRowTitle: string;
511
514
  createdBy: string;
512
515
  updatedBy: string;
516
+ created: string;
517
+ updated: string;
513
518
  showEmptyRelated_one: string;
514
519
  showEmptyRelated_other: string;
515
520
  copyEmail: string;
@@ -105,6 +105,9 @@ const ja = {
105
105
  deleteSuccess: "{{object}}が削除されました",
106
106
  },
107
107
  fields: {
108
+ relativeDate: {
109
+ overdue: "期限超過 {{count}}日",
110
+ },
108
111
  richText: {
109
112
  format: "フォーマット: {{format}}",
110
113
  basicEditorHint: "リッチテキストエディター(基本)",
@@ -510,6 +513,8 @@ const ja = {
510
513
  deleteRowTitle: "レコードを削除",
511
514
  createdBy: "作成者",
512
515
  updatedBy: "更新者",
516
+ created: "作成",
517
+ updated: "更新",
513
518
  showEmptyRelated_one: "+ {{count}} 件(空)",
514
519
  showEmptyRelated_other: "+ {{count}} 件(空)",
515
520
  copyEmail: "メールをコピー",
@@ -105,6 +105,9 @@ declare const ko: {
105
105
  deleteSuccess: string;
106
106
  };
107
107
  fields: {
108
+ relativeDate: {
109
+ overdue: string;
110
+ };
108
111
  richText: {
109
112
  format: string;
110
113
  basicEditorHint: string;
@@ -510,6 +513,8 @@ declare const ko: {
510
513
  highlightFields: string;
511
514
  createdBy: string;
512
515
  updatedBy: string;
516
+ created: string;
517
+ updated: string;
513
518
  showEmptyRelated_one: string;
514
519
  showEmptyRelated_other: string;
515
520
  copyEmail: string;
@@ -105,6 +105,9 @@ const ko = {
105
105
  deleteSuccess: "{{object}} 삭제됨",
106
106
  },
107
107
  fields: {
108
+ relativeDate: {
109
+ overdue: "기한 초과 {{count}}일",
110
+ },
108
111
  richText: {
109
112
  format: "형식: {{format}}",
110
113
  basicEditorHint: "서식 있는 텍스트 편집기 (기본)",
@@ -510,6 +513,8 @@ const ko = {
510
513
  highlightFields: "주요 필드",
511
514
  createdBy: "작성자",
512
515
  updatedBy: "업데이트한 사람",
516
+ created: "작성됨",
517
+ updated: "업데이트됨",
513
518
  showEmptyRelated_one: "+ {{count}}개 비어 있음",
514
519
  showEmptyRelated_other: "+ {{count}}개 비어 있음",
515
520
  copyEmail: "이메일 복사",
@@ -105,6 +105,9 @@ declare const pt: {
105
105
  deleteSuccess: string;
106
106
  };
107
107
  fields: {
108
+ relativeDate: {
109
+ overdue: string;
110
+ };
108
111
  richText: {
109
112
  format: string;
110
113
  basicEditorHint: string;
@@ -105,6 +105,9 @@ const pt = {
105
105
  deleteSuccess: "{{object}} excluído",
106
106
  },
107
107
  fields: {
108
+ relativeDate: {
109
+ overdue: "Atrasado {{count}} d",
110
+ },
108
111
  richText: {
109
112
  format: "Formato: {{format}}",
110
113
  basicEditorHint: "Editor de texto rico (básico)",
@@ -105,6 +105,9 @@ declare const ru: {
105
105
  deleteSuccess: string;
106
106
  };
107
107
  fields: {
108
+ relativeDate: {
109
+ overdue: string;
110
+ };
108
111
  richText: {
109
112
  format: string;
110
113
  basicEditorHint: string;
@@ -105,6 +105,9 @@ const ru = {
105
105
  deleteSuccess: "{{object}} удалён",
106
106
  },
107
107
  fields: {
108
+ relativeDate: {
109
+ overdue: "Просрочено на {{count}} дн.",
110
+ },
108
111
  richText: {
109
112
  format: "Формат: {{format}}",
110
113
  basicEditorHint: "Редактор форматированного текста (базовый)",
@@ -112,6 +112,9 @@ declare const zh: {
112
112
  readonly deleteSuccess: "{{object}}删除成功";
113
113
  };
114
114
  readonly fields: {
115
+ readonly relativeDate: {
116
+ readonly overdue: "逾期 {{count}} 天";
117
+ };
115
118
  readonly richText: {
116
119
  readonly format: "格式: {{format}}";
117
120
  readonly basicEditorHint: "富文本编辑器(基础)";
@@ -678,8 +681,10 @@ declare const zh: {
678
681
  readonly daysAgo: "{{count}}天前";
679
682
  readonly systemActor: "系统";
680
683
  readonly unknownUser: "未知用户";
681
- readonly createdBy: "创建于";
682
- readonly updatedBy: "更新于";
684
+ readonly createdBy: "创建人";
685
+ readonly updatedBy: "更新人";
686
+ readonly created: "创建于";
687
+ readonly updated: "更新于";
683
688
  readonly dropFilesToUpload: "拖拽文件到此处或点击上传";
684
689
  readonly attachmentCount: "{{count}} 个附件";
685
690
  readonly attachmentCountPlural: "{{count}} 个附件";
@@ -961,6 +966,29 @@ declare const zh: {
961
966
  readonly vsYesterday: "较昨日";
962
967
  readonly vsPreviousPeriod: "较上期";
963
968
  };
969
+ readonly filters: {
970
+ readonly label: "仪表盘过滤器";
971
+ readonly dateRange: "日期范围";
972
+ readonly allTime: "全部时间";
973
+ readonly custom: "自定义…";
974
+ readonly all: "全部";
975
+ readonly reset: "重置";
976
+ readonly range: {
977
+ readonly today: "今天";
978
+ readonly yesterday: "昨天";
979
+ readonly this_week: "本周";
980
+ readonly last_week: "上周";
981
+ readonly this_month: "本月";
982
+ readonly last_month: "上月";
983
+ readonly this_quarter: "本季度";
984
+ readonly last_quarter: "上季度";
985
+ readonly this_year: "今年";
986
+ readonly last_year: "去年";
987
+ readonly last_7_days: "近 7 天";
988
+ readonly last_30_days: "近 30 天";
989
+ readonly last_90_days: "近 90 天";
990
+ };
991
+ };
964
992
  };
965
993
  readonly configPanel: {
966
994
  readonly save: "保存";
@@ -1244,6 +1272,19 @@ declare const zh: {
1244
1272
  readonly createApp: "创建新应用";
1245
1273
  };
1246
1274
  readonly ai: {
1275
+ readonly usage: {
1276
+ readonly title: "AI 用量";
1277
+ readonly meterBuild: "AI 搭建";
1278
+ readonly meterAsk: "数据问询";
1279
+ readonly statusOk: "额度充足";
1280
+ readonly statusLow: "即将用完";
1281
+ readonly statusFull: "额度已用完";
1282
+ readonly resetsDaily: "今晚重置";
1283
+ readonly resetsMonthly: "下个周期重置";
1284
+ readonly ctaUpgrade: "升级以继续使用";
1285
+ readonly ctaTopUp: "购买额度包以继续";
1286
+ readonly ariaLabel: "AI 用量:{{status}}";
1287
+ };
1247
1288
  readonly workspaceTitle: "AI 工作区";
1248
1289
  readonly workspaceSubtitle: "提问、查看并继续历史对话";
1249
1290
  readonly openChats: "打开对话列表";
@@ -1270,6 +1311,8 @@ declare const zh: {
1270
1311
  readonly sendFailedGeneric: "消息发送失败,请重试。你的消息已保留在输入框中。";
1271
1312
  readonly askAgent: "向 {{agent}} 提问...";
1272
1313
  readonly assistant: "助手";
1314
+ readonly liveCanvas: "草稿预览 · {{app}}";
1315
+ readonly liveCanvasUnlisted: "运行预览 · {{app}}(未发布 · 仅自己可见)";
1273
1316
  readonly loadingAgents: "正在加载助手...";
1274
1317
  readonly askAnything: "输入你的问题...";
1275
1318
  readonly emptyTitle: "开始对话";
@@ -1285,6 +1328,11 @@ declare const zh: {
1285
1328
  readonly title: "向你的数据提问";
1286
1329
  readonly description: "针对你的记录提问 —— 在你有权访问的数据范围内进行计数、列举和汇总。";
1287
1330
  };
1331
+ readonly editApp: {
1332
+ readonly title: "正在编辑「{{app}}」";
1333
+ readonly titleGeneric: "编辑此应用";
1334
+ readonly description: "想改点什么?我会就地修改这个应用 —— 加字段、对象、视图或自动化,或调整已有内容。";
1335
+ };
1288
1336
  };
1289
1337
  readonly clearConversation: "清空";
1290
1338
  readonly sendHint: "发送";
@@ -1348,6 +1396,12 @@ declare const zh: {
1348
1396
  readonly availableObjects: "列出可用的数据对象。";
1349
1397
  readonly recentActivity: "总结我的最近动态。";
1350
1398
  };
1399
+ readonly editApp: {
1400
+ readonly addField: "给某个对象加一个字段。";
1401
+ readonly addObject: "新增一个对象,并关联到已有对象。";
1402
+ readonly addDashboard: "加一个展示关键指标的仪表盘。";
1403
+ readonly addAutomation: "加一个自动化 —— 审批、状态流转或通知。";
1404
+ };
1351
1405
  };
1352
1406
  };
1353
1407
  readonly errors: {
@@ -112,6 +112,9 @@ const zh = {
112
112
  deleteSuccess: '{{object}}删除成功',
113
113
  },
114
114
  fields: {
115
+ relativeDate: {
116
+ overdue: '逾期 {{count}} 天',
117
+ },
115
118
  richText: {
116
119
  format: '格式: {{format}}',
117
120
  basicEditorHint: '富文本编辑器(基础)',
@@ -690,9 +693,13 @@ const zh = {
690
693
  // Activity feed actors
691
694
  systemActor: '系统',
692
695
  unknownUser: '未知用户',
693
- // Record meta footer (audit provenance)
694
- createdBy: '创建于',
695
- updatedBy: '更新于',
696
+ // Record meta footer (audit provenance)。createdBy/updatedBy 后面跟的是
697
+ // 操作者("创建人 Dev Admin · 5 分钟前");created/updated 是无操作者时的
698
+ // 兜底("创建于 5 分钟前")。旧文案把"创建于"用在了操作者位置,属误译。
699
+ createdBy: '创建人',
700
+ updatedBy: '更新人',
701
+ created: '创建于',
702
+ updated: '更新于',
696
703
  // Attachments
697
704
  dropFilesToUpload: '拖拽文件到此处或点击上传',
698
705
  attachmentCount: '{{count}} 个附件',
@@ -983,6 +990,29 @@ const zh = {
983
990
  vsYesterday: '较昨日',
984
991
  vsPreviousPeriod: '较上期',
985
992
  },
993
+ filters: {
994
+ label: '仪表盘过滤器',
995
+ dateRange: '日期范围',
996
+ allTime: '全部时间',
997
+ custom: '自定义…',
998
+ all: '全部',
999
+ reset: '重置',
1000
+ range: {
1001
+ today: '今天',
1002
+ yesterday: '昨天',
1003
+ this_week: '本周',
1004
+ last_week: '上周',
1005
+ this_month: '本月',
1006
+ last_month: '上月',
1007
+ this_quarter: '本季度',
1008
+ last_quarter: '上季度',
1009
+ this_year: '今年',
1010
+ last_year: '去年',
1011
+ last_7_days: '近 7 天',
1012
+ last_30_days: '近 30 天',
1013
+ last_90_days: '近 90 天',
1014
+ },
1015
+ },
986
1016
  },
987
1017
  configPanel: {
988
1018
  save: '保存',
@@ -1266,6 +1296,19 @@ const zh = {
1266
1296
  createApp: '创建新应用',
1267
1297
  },
1268
1298
  ai: {
1299
+ usage: {
1300
+ title: 'AI 用量',
1301
+ meterBuild: 'AI 搭建',
1302
+ meterAsk: '数据问询',
1303
+ statusOk: '额度充足',
1304
+ statusLow: '即将用完',
1305
+ statusFull: '额度已用完',
1306
+ resetsDaily: '今晚重置',
1307
+ resetsMonthly: '下个周期重置',
1308
+ ctaUpgrade: '升级以继续使用',
1309
+ ctaTopUp: '购买额度包以继续',
1310
+ ariaLabel: 'AI 用量:{{status}}',
1311
+ },
1269
1312
  workspaceTitle: 'AI 工作区',
1270
1313
  workspaceSubtitle: '提问、查看并继续历史对话',
1271
1314
  openChats: '打开对话列表',
@@ -1292,6 +1335,8 @@ const zh = {
1292
1335
  sendFailedGeneric: '消息发送失败,请重试。你的消息已保留在输入框中。',
1293
1336
  askAgent: '向 {{agent}} 提问...',
1294
1337
  assistant: '助手',
1338
+ liveCanvas: '草稿预览 · {{app}}',
1339
+ liveCanvasUnlisted: '运行预览 · {{app}}(未发布 · 仅自己可见)',
1295
1340
  loadingAgents: '正在加载助手...',
1296
1341
  askAnything: '输入你的问题...',
1297
1342
  emptyTitle: '开始对话',
@@ -1307,6 +1352,11 @@ const zh = {
1307
1352
  title: '向你的数据提问',
1308
1353
  description: '针对你的记录提问 —— 在你有权访问的数据范围内进行计数、列举和汇总。',
1309
1354
  },
1355
+ editApp: {
1356
+ title: '正在编辑「{{app}}」',
1357
+ titleGeneric: '编辑此应用',
1358
+ description: '想改点什么?我会就地修改这个应用 —— 加字段、对象、视图或自动化,或调整已有内容。',
1359
+ },
1310
1360
  },
1311
1361
  clearConversation: '清空',
1312
1362
  sendHint: '发送',
@@ -1378,6 +1428,12 @@ const zh = {
1378
1428
  availableObjects: '列出可用的数据对象。',
1379
1429
  recentActivity: '总结我的最近动态。',
1380
1430
  },
1431
+ editApp: {
1432
+ addField: '给某个对象加一个字段。',
1433
+ addObject: '新增一个对象,并关联到已有对象。',
1434
+ addDashboard: '加一个展示关键指标的仪表盘。',
1435
+ addAutomation: '加一个自动化 —— 审批、状态流转或通知。',
1436
+ },
1381
1437
  },
1382
1438
  },
1383
1439
  errors: {
@@ -10,38 +10,32 @@
10
10
  */
11
11
  import { useObjectTranslation } from './provider';
12
12
  export function createSafeTranslation(defaults, testKey) {
13
- return function useSafeTranslation() {
14
- try {
15
- const result = useObjectTranslation();
16
- const testValue = result.t(testKey);
17
- if (testValue === testKey) {
18
- return {
19
- t: (key, options) => {
20
- let value = defaults[key] || key;
21
- if (options) {
22
- for (const [k, v] of Object.entries(options)) {
23
- value = value.replace(`{{${k}}}`, String(v));
24
- }
25
- }
26
- return value;
27
- },
28
- };
13
+ // Factory-level fallback: one stable reference per defaults map, so
14
+ // downstream useMemo/useCallback deps don't invalidate every render in
15
+ // the no-translations case.
16
+ const fallbackT = (key, options) => {
17
+ let value = defaults[key] || key;
18
+ if (options) {
19
+ for (const [k, v] of Object.entries(options)) {
20
+ value = value.replace(`{{${k}}}`, String(v));
29
21
  }
30
- return { t: result.t };
31
22
  }
32
- catch {
33
- return {
34
- t: (key, options) => {
35
- let value = defaults[key] || key;
36
- if (options) {
37
- for (const [k, v] of Object.entries(options)) {
38
- value = value.replace(`{{${k}}}`, String(v));
39
- }
40
- }
41
- return value;
42
- },
43
- };
23
+ return value;
24
+ };
25
+ return function useSafeTranslation() {
26
+ // No try/catch around the hook: useObjectTranslation is provider-safe
27
+ // (optional context read + react-i18next global-instance fallback), and
28
+ // wrapping a hook call in try/catch violates rules-of-hooks — a throw
29
+ // after the hook ran would desync hook order on the next render (same
30
+ // fix as objectui#2595/#2596; this factory closure just escaped the
31
+ // static lint). The testKey probe below carries the actual
32
+ // "translations not configured" fallback.
33
+ const result = useObjectTranslation();
34
+ const testValue = result.t(testKey);
35
+ if (testValue === testKey) {
36
+ return { t: fallbackT };
44
37
  }
38
+ return { t: result.t };
45
39
  };
46
40
  }
47
41
  /**
@@ -57,16 +51,11 @@ export function createSafeTranslation(defaults, testKey) {
57
51
  * `tt(['common.total', 'dashboard.total'], 'Total')`.
58
52
  */
59
53
  export function useSafeTranslate() {
60
- let t;
61
- try {
62
- t = useObjectTranslation().t;
63
- }
64
- catch {
65
- t = undefined;
66
- }
54
+ // Unconditional hook call (rules-of-hooks) — the hook is provider-safe,
55
+ // and a missing translation surfaces as `t(key) === key` per key below,
56
+ // never as a throw. Same fix as createSafeTranslation above.
57
+ const { t } = useObjectTranslation();
67
58
  return (keyOrKeys, fallback) => {
68
- if (!t)
69
- return fallback;
70
59
  const keys = Array.isArray(keyOrKeys) ? keyOrKeys : [keyOrKeys];
71
60
  for (const key of keys) {
72
61
  const v = t(key);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@object-ui/i18n",
3
- "version": "14.0.0",
3
+ "version": "14.1.0",
4
4
  "type": "module",
5
5
  "sideEffects": false,
6
6
  "license": "MIT",