@object-ui/i18n 11.3.0 → 11.5.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,63 @@
1
1
  # @object-ui/i18n
2
2
 
3
+ ## 11.5.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 544d8eb: Add the app → Studio reverse bridge (ADR-0080): workspace admins see a "Design in Studio" entry in the app top bar that deep-links to the running app's owning package on the Studio design surface (`/studio/:packageId/data`). Hidden for non-admins and for apps with no owning package; package writability stays server-side (read-only packages open as browse-only).
8
+ - 1072701: Import wizard: use registered server-side import mappings (framework #2611). When an object has `mapping` metadata artifacts targeting it, the wizard shows a "Saved mapping" selector; picking one hands rename + transforms + write semantics to the server (the artifact is authoritative), replaces the manual column table with a read-only summary of the mapping, and submits `mappingName` over source-header rows (mutually exclusive with the inline column rename). `ImportRequestOptions` gains `mappingName`; the objectstack adapter gains `listImportMappings(objectName)` (feature-detected — the selector simply doesn't appear when unsupported). New `grid.import.*` strings added across all locales.
9
+
10
+ ## 11.4.0
11
+
12
+ ### Patch Changes
13
+
14
+ - 9cd9be1: fix(plugin-grid): make the import wizard's preview step readable — wider columns + friendlier validation errors
15
+
16
+ Two problems on the import wizard's 预览 (preview) step:
17
+
18
+ - **Cramped preview table.** With many mapped columns crammed into the fixed
19
+ dialog width, each header collapsed to one character per line (`关联排班计划`
20
+ stacked vertically) and became unreadable. Columns now get a `min-width` and
21
+ headers no longer wrap, so the preview area scrolls horizontally instead of
22
+ crushing every column.
23
+
24
+ - **Unreadable dry-run error messages.** A reference cell that couldn't resolve
25
+ rendered as `第 1 行: product: product: no os_tianshun_ehr_product matches "导管架"`
26
+ — the field named twice, an internal object api-name leaking through, all in
27
+ English. The server already tags each failure with a structured `code`, so we
28
+ now drive the message off that code (localized, with the offending value),
29
+ resolve the field's api-name to its label, and only fall back to the raw
30
+ server text — minus the duplicated prefix — for unrecognized codes. The same
31
+ row now reads `第 1 行: 产品:找不到匹配 "导管架" 的记录`.
32
+
33
+ - 790558b: fix(studio): make the Automations and Interfaces pillars authorable in a fresh package
34
+
35
+ Dogfooding a brand-new package end-to-end (design objects → automations →
36
+ interfaces → publish → use) surfaced two blocking dead-ends in the pillar
37
+ Studio, both now fixed:
38
+
39
+ - **Automations pillar had no way to create a flow.** For a package with zero
40
+ flows the rail rendered an endless "加载中…" (loading conflated with empty)
41
+ and offered no create affordance, so automations could never be authored.
42
+ It now tracks the list-loaded state (real empty state "还没有自动化 — 点「新建」开始")
43
+ and has a "+ 新建" inline creator that saves a minimal, valid `start → end`
44
+ autolaunched flow skeleton as a draft and opens it in the flow designer.
45
+
46
+ - **Interfaces nav items could not be bound to a target — and silently failed
47
+ to save.** Selecting a nav item showed no inspector, and the item shape the
48
+ editor produced (`{ label, object }`, no `id`/`type`) failed the app spec's
49
+ navigation union ("navigation.N: Invalid input"), so the draft never
50
+ persisted and the published app navigation stayed empty. The right panel now
51
+ renders a `StudioNavItemInspector` with a business-friendly object picker
52
+ (populated from the package's published ∪ draft objects) that emits a
53
+ spec-valid `ObjectNavItem` (`{ id, type:'object', objectName, label }`), and
54
+ the nav save drops still-unbound placeholders + backfills a snake_case id so
55
+ one blank item can't fail the whole save.
56
+
57
+ Also fills in the Home builder-cover i18n keys (`home.build.*`,
58
+ `home.template.*`) in `en`/`zh` so the "Build an app" / "Start with a template"
59
+ cards resolve real strings instead of falling back to defaults.
60
+
3
61
  ## 11.3.0
4
62
 
5
63
  ### Patch Changes
@@ -191,6 +191,12 @@ declare const ar: {
191
191
  templateName: string;
192
192
  save: string;
193
193
  deleteTemplate: string;
194
+ savedMapping: string;
195
+ chooseSavedMapping: string;
196
+ manualMapping: string;
197
+ transform: string;
198
+ savedMappingHint: string;
199
+ savedMappingPreviewNote: string;
194
200
  csvColumn: string;
195
201
  mapsTo: string;
196
202
  typeMismatch: string;
@@ -1263,6 +1269,7 @@ declare const ar: {
1263
1269
  };
1264
1270
  topbar: {
1265
1271
  aiAssistant: string;
1272
+ designInStudio: string;
1266
1273
  };
1267
1274
  home: {
1268
1275
  title: string;
@@ -1988,6 +1995,12 @@ declare const ar: {
1988
1995
  empty: string;
1989
1996
  kindNew: string;
1990
1997
  kindUpdate: string;
1998
+ detailLoading: string;
1999
+ detailLoadFailed: string;
2000
+ detailNone: string;
2001
+ detailChangedKeys: string;
2002
+ confirmNote: string;
2003
+ publishConfirm: string;
1991
2004
  };
1992
2005
  };
1993
2006
  filterBuilder: {
@@ -191,6 +191,12 @@ const ar = {
191
191
  templateName: "اسم القالب",
192
192
  save: "حفظ",
193
193
  deleteTemplate: "حذف القالب",
194
+ savedMapping: 'Saved mapping:',
195
+ chooseSavedMapping: 'Choose a saved mapping…',
196
+ manualMapping: '— Map columns manually —',
197
+ transform: 'Transform',
198
+ savedMappingHint: 'Mapping “{{name}}” applies rename + transforms + type coercion on the server. Column mapping is read-only.',
199
+ savedMappingPreviewNote: 'The preview shows your source columns; on import, mapping “{{name}}” applies rename, transforms and type coercion on the server.',
194
200
  csvColumn: "العمود",
195
201
  mapsTo: "يُعيَّن إلى",
196
202
  typeMismatch: "يبدو أنه {{type}}",
@@ -1263,6 +1269,7 @@ const ar = {
1263
1269
  },
1264
1270
  topbar: {
1265
1271
  aiAssistant: "مساعد الذكاء الاصطناعي",
1272
+ designInStudio: "التصميم في Studio",
1266
1273
  },
1267
1274
  home: {
1268
1275
  title: "الرئيسية",
@@ -1988,6 +1995,12 @@ const ar = {
1988
1995
  empty: 'لا شيء معلّق — نُشرت كل المسودات.',
1989
1996
  kindNew: 'جديد',
1990
1997
  kindUpdate: 'تحديث',
1998
+ detailLoading: 'جارٍ تحميل التفاصيل…',
1999
+ detailLoadFailed: 'تعذر تحميل تفاصيل التغيير:',
2000
+ detailNone: 'لم يتم اكتشاف اختلافات — المسودة مطابقة للنسخة المنشورة.',
2001
+ detailChangedKeys: 'تغييرات أخرى:',
2002
+ confirmNote: 'النشر يُصدر كل المسودات المعلقة ({{count}}) لهذه الحزمة دفعة واحدة.',
2003
+ publishConfirm: 'نشر الكل',
1991
2004
  },
1992
2005
  },
1993
2006
  filterBuilder: {
@@ -191,6 +191,12 @@ declare const de: {
191
191
  templateName: string;
192
192
  save: string;
193
193
  deleteTemplate: string;
194
+ savedMapping: string;
195
+ chooseSavedMapping: string;
196
+ manualMapping: string;
197
+ transform: string;
198
+ savedMappingHint: string;
199
+ savedMappingPreviewNote: string;
194
200
  csvColumn: string;
195
201
  mapsTo: string;
196
202
  typeMismatch: string;
@@ -1263,6 +1269,7 @@ declare const de: {
1263
1269
  };
1264
1270
  topbar: {
1265
1271
  aiAssistant: string;
1272
+ designInStudio: string;
1266
1273
  };
1267
1274
  home: {
1268
1275
  title: string;
@@ -1988,6 +1995,12 @@ declare const de: {
1988
1995
  empty: string;
1989
1996
  kindNew: string;
1990
1997
  kindUpdate: string;
1998
+ detailLoading: string;
1999
+ detailLoadFailed: string;
2000
+ detailNone: string;
2001
+ detailChangedKeys: string;
2002
+ confirmNote: string;
2003
+ publishConfirm: string;
1991
2004
  };
1992
2005
  };
1993
2006
  filterBuilder: {
@@ -191,6 +191,12 @@ const de = {
191
191
  templateName: "Vorlagenname",
192
192
  save: "Speichern",
193
193
  deleteTemplate: "Vorlage löschen",
194
+ savedMapping: 'Saved mapping:',
195
+ chooseSavedMapping: 'Choose a saved mapping…',
196
+ manualMapping: '— Map columns manually —',
197
+ transform: 'Transform',
198
+ savedMappingHint: 'Mapping “{{name}}” applies rename + transforms + type coercion on the server. Column mapping is read-only.',
199
+ savedMappingPreviewNote: 'The preview shows your source columns; on import, mapping “{{name}}” applies rename, transforms and type coercion on the server.',
194
200
  csvColumn: "Spalte",
195
201
  mapsTo: "Zugeordnet zu",
196
202
  typeMismatch: "Sieht aus wie {{type}}",
@@ -1263,6 +1269,7 @@ const de = {
1263
1269
  },
1264
1270
  topbar: {
1265
1271
  aiAssistant: "KI-Assistent",
1272
+ designInStudio: "Im Studio gestalten",
1266
1273
  },
1267
1274
  home: {
1268
1275
  title: "Startseite",
@@ -1988,6 +1995,12 @@ const de = {
1988
1995
  empty: 'Nichts ausstehend — alle Entwürfe wurden veröffentlicht.',
1989
1996
  kindNew: 'Neu',
1990
1997
  kindUpdate: 'Aktualisierung',
1998
+ detailLoading: 'Details werden geladen…',
1999
+ detailLoadFailed: 'Änderungsdetails konnten nicht geladen werden:',
2000
+ detailNone: 'Keine Unterschiede erkannt — der Entwurf entspricht der veröffentlichten Version.',
2001
+ detailChangedKeys: 'Ebenfalls geändert:',
2002
+ confirmNote: 'Beim Veröffentlichen werden alle {{count}} ausstehenden Entwürfe dieses Pakets atomar freigegeben.',
2003
+ publishConfirm: 'Alle veröffentlichen',
1991
2004
  },
1992
2005
  },
1993
2006
  filterBuilder: {
@@ -161,6 +161,12 @@ declare const en: {
161
161
  readonly refreshing: "Refreshing…";
162
162
  readonly openRecord: "Open record";
163
163
  readonly openMenu: "Open menu";
164
+ readonly bulkSelected: "{{count}} selected";
165
+ readonly bulkSelectedAllMatches: "{{count}} selected (all matches)";
166
+ readonly bulkClear: "Clear";
167
+ readonly bulkAllOnPage: "All {{count}} on this page are selected.";
168
+ readonly bulkSelectAllMatching: "Select all {{count}} matching";
169
+ readonly bulkAllMatchingSelected: "All {{count}} matching records are selected.";
164
170
  readonly rowHeight: "Row height: {{mode}}";
165
171
  readonly empty: "Empty";
166
172
  readonly yes: "Yes";
@@ -198,6 +204,12 @@ declare const en: {
198
204
  readonly templateName: "Template name";
199
205
  readonly save: "Save";
200
206
  readonly deleteTemplate: "Delete template";
207
+ readonly savedMapping: "Saved mapping:";
208
+ readonly chooseSavedMapping: "Choose a saved mapping…";
209
+ readonly manualMapping: "— Map columns manually —";
210
+ readonly transform: "Transform";
211
+ readonly savedMappingHint: "Mapping “{{name}}” applies rename + transforms + type coercion on the server. Column mapping is read-only.";
212
+ readonly savedMappingPreviewNote: "The preview shows your source columns; on import, mapping “{{name}}” applies rename, transforms and type coercion on the server.";
201
213
  readonly csvColumn: "Column";
202
214
  readonly mapsTo: "Maps To";
203
215
  readonly typeMismatch: "Looks like {{type}}";
@@ -231,6 +243,31 @@ declare const en: {
231
243
  readonly requiredMark: "*";
232
244
  readonly required: "Required";
233
245
  readonly invalidType: "Invalid {{type}}";
246
+ readonly legacyReferenceBlocked: "Import blocked: {{fields}} are relation fields that need the server import route to resolve names into record IDs, and this connection doesn’t support it. Importing them as plain text would corrupt the data. Upgrade the backend/client, or unmap these columns and import them separately.";
247
+ };
248
+ readonly bulk: {
249
+ readonly confirmDefault: "This will apply to {{count}} record(s).";
250
+ readonly overLimit: "Selection ({{count}}) exceeds the action limit ({{limit}}). Reduce the selection to proceed.";
251
+ readonly affectedRecords: "Affected records ({{count}}):";
252
+ readonly rowFallback: "Row {{index}}";
253
+ readonly andMore: "… and {{count}} more";
254
+ readonly processed: "{{count}} / {{total}} processed";
255
+ readonly processedFailed: " · {{count}} failed";
256
+ readonly undonePrefix: "Undone — ";
257
+ readonly succeeded: "Succeeded {{count}} / {{total}}";
258
+ readonly resultFailed: " · Failed {{count}}";
259
+ readonly retry: "Retry";
260
+ readonly downloadErrorCsv: "Download error CSV";
261
+ readonly cancel: "Cancel";
262
+ readonly back: "Back";
263
+ readonly next: "Next";
264
+ readonly run: "Run";
265
+ readonly running: "Running…";
266
+ readonly undo: "Undo";
267
+ readonly undoing: "Undoing…";
268
+ readonly done: "Done";
269
+ readonly selectPlaceholder: "Select…";
270
+ readonly loading: "Loading…";
234
271
  };
235
272
  };
236
273
  readonly calendar: {
@@ -305,6 +342,9 @@ declare const en: {
305
342
  readonly addGroup: "Add group field";
306
343
  readonly collapsedByDefault: "Collapsed by default";
307
344
  readonly removeGroup: "Remove";
345
+ readonly inlineEditShort: "Edit inline";
346
+ readonly inlineEditLabel: "Edit records inline (click a cell to edit)";
347
+ readonly recordEditingTitle: "Record editing";
308
348
  };
309
349
  readonly kanban: {
310
350
  readonly addCard: "Add card";
@@ -1208,6 +1248,15 @@ declare const en: {
1208
1248
  readonly dark: "Dark";
1209
1249
  readonly system: "System";
1210
1250
  };
1251
+ readonly objectData: {
1252
+ readonly badge: "Data";
1253
+ readonly description: "URL-defined data slice — not bound to any saved view.";
1254
+ readonly filteredBy: "Filtered by";
1255
+ readonly removeFilter: "Remove filter {{field}}";
1256
+ readonly saveAsView: "Save as view";
1257
+ readonly noAccessTitle: "Access denied";
1258
+ readonly noAccess: "You do not have permission to view this data.";
1259
+ };
1211
1260
  readonly objectView: {
1212
1261
  readonly objectNotFound: "Object Not Found";
1213
1262
  readonly objectNotFoundDescription: "The object \"{{objectName}}\" does not exist in the current configuration.";
@@ -1612,6 +1661,7 @@ declare const en: {
1612
1661
  };
1613
1662
  readonly topbar: {
1614
1663
  readonly aiAssistant: "AI Assistant";
1664
+ readonly designInStudio: "Design in Studio";
1615
1665
  readonly openAssistant: "Open {{name}} assistant";
1616
1666
  readonly offline: "Offline";
1617
1667
  readonly usersOnline: "Users currently online";
@@ -1634,6 +1684,14 @@ declare const en: {
1634
1684
  readonly greetingEvening: "Good evening";
1635
1685
  readonly greetingNight: "Working late";
1636
1686
  readonly heroTagline: "Pick up where you left off, or explore something new.";
1687
+ readonly build: {
1688
+ readonly title: "Build an app";
1689
+ readonly subtitle: "Start from scratch — design objects, forms, automations and interfaces.";
1690
+ };
1691
+ readonly template: {
1692
+ readonly title: "Start with a template";
1693
+ readonly subtitle: "Install a template app from the marketplace and customize it.";
1694
+ };
1637
1695
  readonly open: "Open";
1638
1696
  readonly stats: {
1639
1697
  readonly apps: "Applications";
@@ -1705,6 +1763,7 @@ declare const en: {
1705
1763
  readonly appsAvailable: "{{count}} apps available";
1706
1764
  readonly addApp: "Add App";
1707
1765
  readonly editApp: "Edit App";
1766
+ readonly editNavigation: "Edit Navigation";
1708
1767
  readonly manageAllApps: "Manage All Apps";
1709
1768
  readonly systemConsole: "System Console";
1710
1769
  readonly noAppsConfigured: "No apps configured";
@@ -1808,6 +1867,12 @@ declare const en: {
1808
1867
  readonly empty: "Nothing pending — every draft has been published.";
1809
1868
  readonly kindNew: "New";
1810
1869
  readonly kindUpdate: "Update";
1870
+ readonly detailLoading: "Loading detail…";
1871
+ readonly detailLoadFailed: "Could not load change detail:";
1872
+ readonly detailNone: "No differences detected — the draft matches the published version.";
1873
+ readonly detailChangedKeys: "Also changed:";
1874
+ readonly confirmNote: "Publishing releases all {{count}} pending drafts of this package atomically.";
1875
+ readonly publishConfirm: "Publish all";
1811
1876
  };
1812
1877
  };
1813
1878
  readonly renderer: {
@@ -161,6 +161,12 @@ const en = {
161
161
  refreshing: 'Refreshing…',
162
162
  openRecord: 'Open record',
163
163
  openMenu: 'Open menu',
164
+ bulkSelected: '{{count}} selected',
165
+ bulkSelectedAllMatches: '{{count}} selected (all matches)',
166
+ bulkClear: 'Clear',
167
+ bulkAllOnPage: 'All {{count}} on this page are selected.',
168
+ bulkSelectAllMatching: 'Select all {{count}} matching',
169
+ bulkAllMatchingSelected: 'All {{count}} matching records are selected.',
164
170
  rowHeight: 'Row height: {{mode}}',
165
171
  empty: 'Empty',
166
172
  yes: 'Yes',
@@ -198,6 +204,12 @@ const en = {
198
204
  templateName: 'Template name',
199
205
  save: 'Save',
200
206
  deleteTemplate: 'Delete template',
207
+ savedMapping: 'Saved mapping:',
208
+ chooseSavedMapping: 'Choose a saved mapping…',
209
+ manualMapping: '— Map columns manually —',
210
+ transform: 'Transform',
211
+ savedMappingHint: 'Mapping “{{name}}” applies rename + transforms + type coercion on the server. Column mapping is read-only.',
212
+ savedMappingPreviewNote: 'The preview shows your source columns; on import, mapping “{{name}}” applies rename, transforms and type coercion on the server.',
201
213
  csvColumn: 'Column',
202
214
  mapsTo: 'Maps To',
203
215
  typeMismatch: 'Looks like {{type}}',
@@ -231,6 +243,31 @@ const en = {
231
243
  requiredMark: '*',
232
244
  required: 'Required',
233
245
  invalidType: 'Invalid {{type}}',
246
+ legacyReferenceBlocked: 'Import blocked: {{fields}} are relation fields that need the server import route to resolve names into record IDs, and this connection doesn\u2019t support it. Importing them as plain text would corrupt the data. Upgrade the backend/client, or unmap these columns and import them separately.',
247
+ },
248
+ bulk: {
249
+ confirmDefault: 'This will apply to {{count}} record(s).',
250
+ overLimit: 'Selection ({{count}}) exceeds the action limit ({{limit}}). Reduce the selection to proceed.',
251
+ affectedRecords: 'Affected records ({{count}}):',
252
+ rowFallback: 'Row {{index}}',
253
+ andMore: '\u2026 and {{count}} more',
254
+ processed: '{{count}} / {{total}} processed',
255
+ processedFailed: ' \u00b7 {{count}} failed',
256
+ undonePrefix: 'Undone \u2014 ',
257
+ succeeded: 'Succeeded {{count}} / {{total}}',
258
+ resultFailed: ' \u00b7 Failed {{count}}',
259
+ retry: 'Retry',
260
+ downloadErrorCsv: 'Download error CSV',
261
+ cancel: 'Cancel',
262
+ back: 'Back',
263
+ next: 'Next',
264
+ run: 'Run',
265
+ running: 'Running\u2026',
266
+ undo: 'Undo',
267
+ undoing: 'Undoing\u2026',
268
+ done: 'Done',
269
+ selectPlaceholder: 'Select\u2026',
270
+ loading: 'Loading\u2026',
234
271
  },
235
272
  },
236
273
  calendar: {
@@ -305,6 +342,9 @@ const en = {
305
342
  addGroup: 'Add group field',
306
343
  collapsedByDefault: 'Collapsed by default',
307
344
  removeGroup: 'Remove',
345
+ inlineEditShort: 'Edit inline',
346
+ inlineEditLabel: 'Edit records inline (click a cell to edit)',
347
+ recordEditingTitle: 'Record editing',
308
348
  },
309
349
  kanban: {
310
350
  addCard: 'Add card',
@@ -1224,6 +1264,15 @@ const en = {
1224
1264
  dark: 'Dark',
1225
1265
  system: 'System',
1226
1266
  },
1267
+ objectData: {
1268
+ badge: 'Data',
1269
+ description: 'URL-defined data slice — not bound to any saved view.',
1270
+ filteredBy: 'Filtered by',
1271
+ removeFilter: 'Remove filter {{field}}',
1272
+ saveAsView: 'Save as view',
1273
+ noAccessTitle: 'Access denied',
1274
+ noAccess: 'You do not have permission to view this data.',
1275
+ },
1227
1276
  objectView: {
1228
1277
  objectNotFound: 'Object Not Found',
1229
1278
  objectNotFoundDescription: 'The object "{{objectName}}" does not exist in the current configuration.',
@@ -1628,6 +1677,7 @@ const en = {
1628
1677
  },
1629
1678
  topbar: {
1630
1679
  aiAssistant: 'AI Assistant',
1680
+ designInStudio: 'Design in Studio',
1631
1681
  openAssistant: 'Open {{name}} assistant',
1632
1682
  offline: 'Offline',
1633
1683
  usersOnline: 'Users currently online',
@@ -1650,6 +1700,14 @@ const en = {
1650
1700
  greetingEvening: 'Good evening',
1651
1701
  greetingNight: 'Working late',
1652
1702
  heroTagline: 'Pick up where you left off, or explore something new.',
1703
+ build: {
1704
+ title: 'Build an app',
1705
+ subtitle: 'Start from scratch — design objects, forms, automations and interfaces.',
1706
+ },
1707
+ template: {
1708
+ title: 'Start with a template',
1709
+ subtitle: 'Install a template app from the marketplace and customize it.',
1710
+ },
1653
1711
  open: 'Open',
1654
1712
  stats: {
1655
1713
  apps: 'Applications',
@@ -1721,6 +1779,7 @@ const en = {
1721
1779
  appsAvailable: '{{count}} apps available',
1722
1780
  addApp: 'Add App',
1723
1781
  editApp: 'Edit App',
1782
+ editNavigation: 'Edit Navigation',
1724
1783
  manageAllApps: 'Manage All Apps',
1725
1784
  systemConsole: 'System Console',
1726
1785
  noAppsConfigured: 'No apps configured',
@@ -1827,6 +1886,12 @@ const en = {
1827
1886
  empty: 'Nothing pending — every draft has been published.',
1828
1887
  kindNew: 'New',
1829
1888
  kindUpdate: 'Update',
1889
+ detailLoading: 'Loading detail…',
1890
+ detailLoadFailed: 'Could not load change detail:',
1891
+ detailNone: 'No differences detected — the draft matches the published version.',
1892
+ detailChangedKeys: 'Also changed:',
1893
+ confirmNote: 'Publishing releases all {{count}} pending drafts of this package atomically.',
1894
+ publishConfirm: 'Publish all',
1830
1895
  },
1831
1896
  },
1832
1897
  renderer: {
@@ -191,6 +191,12 @@ declare const es: {
191
191
  templateName: string;
192
192
  save: string;
193
193
  deleteTemplate: string;
194
+ savedMapping: string;
195
+ chooseSavedMapping: string;
196
+ manualMapping: string;
197
+ transform: string;
198
+ savedMappingHint: string;
199
+ savedMappingPreviewNote: string;
194
200
  csvColumn: string;
195
201
  mapsTo: string;
196
202
  typeMismatch: string;
@@ -1263,6 +1269,7 @@ declare const es: {
1263
1269
  };
1264
1270
  topbar: {
1265
1271
  aiAssistant: string;
1272
+ designInStudio: string;
1266
1273
  };
1267
1274
  home: {
1268
1275
  title: string;
@@ -1988,6 +1995,12 @@ declare const es: {
1988
1995
  empty: string;
1989
1996
  kindNew: string;
1990
1997
  kindUpdate: string;
1998
+ detailLoading: string;
1999
+ detailLoadFailed: string;
2000
+ detailNone: string;
2001
+ detailChangedKeys: string;
2002
+ confirmNote: string;
2003
+ publishConfirm: string;
1991
2004
  };
1992
2005
  };
1993
2006
  filterBuilder: {
@@ -191,6 +191,12 @@ const es = {
191
191
  templateName: "Nombre de la plantilla",
192
192
  save: "Guardar",
193
193
  deleteTemplate: "Eliminar plantilla",
194
+ savedMapping: 'Saved mapping:',
195
+ chooseSavedMapping: 'Choose a saved mapping…',
196
+ manualMapping: '— Map columns manually —',
197
+ transform: 'Transform',
198
+ savedMappingHint: 'Mapping “{{name}}” applies rename + transforms + type coercion on the server. Column mapping is read-only.',
199
+ savedMappingPreviewNote: 'The preview shows your source columns; on import, mapping “{{name}}” applies rename, transforms and type coercion on the server.',
194
200
  csvColumn: "Columna",
195
201
  mapsTo: "Se asigna a",
196
202
  typeMismatch: "Parece {{type}}",
@@ -1263,6 +1269,7 @@ const es = {
1263
1269
  },
1264
1270
  topbar: {
1265
1271
  aiAssistant: "Asistente de IA",
1272
+ designInStudio: "Diseñar en Studio",
1266
1273
  },
1267
1274
  home: {
1268
1275
  title: "Inicio",
@@ -1988,6 +1995,12 @@ const es = {
1988
1995
  empty: 'Nada pendiente — todos los borradores se han publicado.',
1989
1996
  kindNew: 'Nuevo',
1990
1997
  kindUpdate: 'Actualización',
1998
+ detailLoading: 'Cargando detalles…',
1999
+ detailLoadFailed: 'No se pudieron cargar los detalles del cambio:',
2000
+ detailNone: 'No se detectaron diferencias — el borrador coincide con la versión publicada.',
2001
+ detailChangedKeys: 'También cambió:',
2002
+ confirmNote: 'Publicar libera atómicamente los {{count}} borradores pendientes de este paquete.',
2003
+ publishConfirm: 'Publicar todo',
1991
2004
  },
1992
2005
  },
1993
2006
  filterBuilder: {
@@ -191,6 +191,12 @@ declare const fr: {
191
191
  templateName: string;
192
192
  save: string;
193
193
  deleteTemplate: string;
194
+ savedMapping: string;
195
+ chooseSavedMapping: string;
196
+ manualMapping: string;
197
+ transform: string;
198
+ savedMappingHint: string;
199
+ savedMappingPreviewNote: string;
194
200
  csvColumn: string;
195
201
  mapsTo: string;
196
202
  typeMismatch: string;
@@ -1263,6 +1269,7 @@ declare const fr: {
1263
1269
  };
1264
1270
  topbar: {
1265
1271
  aiAssistant: string;
1272
+ designInStudio: string;
1266
1273
  };
1267
1274
  home: {
1268
1275
  title: string;
@@ -1988,6 +1995,12 @@ declare const fr: {
1988
1995
  empty: string;
1989
1996
  kindNew: string;
1990
1997
  kindUpdate: string;
1998
+ detailLoading: string;
1999
+ detailLoadFailed: string;
2000
+ detailNone: string;
2001
+ detailChangedKeys: string;
2002
+ confirmNote: string;
2003
+ publishConfirm: string;
1991
2004
  };
1992
2005
  };
1993
2006
  filterBuilder: {
@@ -191,6 +191,12 @@ const fr = {
191
191
  templateName: "Nom du modèle",
192
192
  save: "Enregistrer",
193
193
  deleteTemplate: "Supprimer le modèle",
194
+ savedMapping: 'Saved mapping:',
195
+ chooseSavedMapping: 'Choose a saved mapping…',
196
+ manualMapping: '— Map columns manually —',
197
+ transform: 'Transform',
198
+ savedMappingHint: 'Mapping “{{name}}” applies rename + transforms + type coercion on the server. Column mapping is read-only.',
199
+ savedMappingPreviewNote: 'The preview shows your source columns; on import, mapping “{{name}}” applies rename, transforms and type coercion on the server.',
194
200
  csvColumn: "Colonne",
195
201
  mapsTo: "Correspond à",
196
202
  typeMismatch: "Ressemble à {{type}}",
@@ -1263,6 +1269,7 @@ const fr = {
1263
1269
  },
1264
1270
  topbar: {
1265
1271
  aiAssistant: "Assistant IA",
1272
+ designInStudio: "Concevoir dans Studio",
1266
1273
  },
1267
1274
  home: {
1268
1275
  title: "Accueil",
@@ -1988,6 +1995,12 @@ const fr = {
1988
1995
  empty: 'Rien en attente — tous les brouillons ont été publiés.',
1989
1996
  kindNew: 'Nouveau',
1990
1997
  kindUpdate: 'Mise à jour',
1998
+ detailLoading: 'Chargement des détails…',
1999
+ detailLoadFailed: 'Impossible de charger les détails de la modification :',
2000
+ detailNone: 'Aucune différence détectée — le brouillon correspond à la version publiée.',
2001
+ detailChangedKeys: 'Également modifié :',
2002
+ confirmNote: 'La publication libère atomiquement les {{count}} brouillons en attente de ce paquet.',
2003
+ publishConfirm: 'Tout publier',
1991
2004
  },
1992
2005
  },
1993
2006
  filterBuilder: {