@object-ui/i18n 17.5.0 → 17.7.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 +4954 -0
- package/README.md +234 -13
- package/dist/builtinAggregateLabels.d.ts +40 -0
- package/dist/builtinAggregateLabels.js +23 -0
- package/dist/currency.d.ts +27 -3
- package/dist/currency.js +28 -4
- package/dist/fallbackInterpolation.d.ts +79 -0
- package/dist/fallbackInterpolation.js +124 -0
- package/dist/i18n.d.ts +28 -2
- package/dist/i18n.js +99 -17
- package/dist/index.d.ts +17 -23
- package/dist/index.js +51 -27
- package/dist/locales/ar.d.ts +1113 -370
- package/dist/locales/ar.js +1276 -428
- package/dist/locales/de.d.ts +785 -370
- package/dist/locales/de.js +896 -401
- package/dist/locales/en.d.ts +800 -385
- package/dist/locales/en.js +1261 -419
- package/dist/locales/es.d.ts +867 -370
- package/dist/locales/es.js +976 -398
- package/dist/locales/fr.d.ts +867 -370
- package/dist/locales/fr.js +976 -399
- package/dist/locales/index.d.ts +8682 -3761
- package/dist/locales/index.js +68 -29
- package/dist/locales/ja.d.ts +785 -370
- package/dist/locales/ja.js +891 -395
- package/dist/locales/ko.d.ts +785 -370
- package/dist/locales/ko.js +893 -399
- package/dist/locales/pt.d.ts +867 -370
- package/dist/locales/pt.js +975 -397
- package/dist/locales/registry.d.ts +102 -0
- package/dist/locales/registry.js +220 -0
- package/dist/locales/rtl.d.ts +24 -0
- package/dist/locales/rtl.js +26 -0
- package/dist/locales/ru.d.ts +949 -370
- package/dist/locales/ru.js +1093 -419
- package/dist/locales/zh.d.ts +803 -388
- package/dist/locales/zh.js +899 -388
- package/dist/pickLocalized.d.ts +67 -0
- package/dist/pickLocalized.js +114 -0
- package/dist/provider.d.ts +102 -13
- package/dist/provider.js +335 -50
- package/dist/translateFn.d.ts +29 -0
- package/dist/translateFn.js +8 -0
- package/dist/useDisplayLocale.d.ts +11 -0
- package/dist/useDisplayLocale.js +13 -2
- package/dist/useObjectLabel.d.ts +118 -22
- package/dist/useObjectLabel.js +148 -23
- package/dist/useSafeTranslation.js +41 -43
- package/dist/utils/formatting.d.ts +16 -0
- package/dist/utils/formatting.js +23 -3
- package/dist/utils/index.d.ts +4 -4
- package/dist/utils/index.js +4 -4
- package/dist/utils/spec-formatters.d.ts +13 -23
- package/dist/utils/spec-formatters.js +41 -2
- package/dist/utils/spec-translations.d.ts +16 -3
- package/dist/utils/spec-translations.js +52 -13
- package/package.json +12 -6
package/dist/locales/en.js
CHANGED
|
@@ -30,35 +30,42 @@ const en = {
|
|
|
30
30
|
manage_users: 'Manage Users',
|
|
31
31
|
manage_org_users: 'Manage Organization Users',
|
|
32
32
|
manage_metadata: 'Manage Metadata',
|
|
33
|
+
manage_org_presentation: 'Manage Organization Presentation',
|
|
33
34
|
manage_platform_settings: 'Manage Platform Settings',
|
|
34
35
|
setup_access: 'Setup Access',
|
|
35
36
|
setup_write: 'Write Settings',
|
|
36
37
|
studio_access: 'Studio Access',
|
|
38
|
+
manage_sharing: 'Manage Sharing',
|
|
37
39
|
},
|
|
38
40
|
},
|
|
39
41
|
// objectui#3546 slice six — the read-only facet summary + Studio deep-link a
|
|
40
42
|
// `sys_permission_set` record shows for its six authorization facets
|
|
41
43
|
// (ADR-0056 P1, plugin-detail's PermissionFacetLink).
|
|
42
44
|
//
|
|
43
|
-
// The four count labels are plural families.
|
|
44
|
-
//
|
|
45
|
-
//
|
|
46
|
-
//
|
|
47
|
-
//
|
|
48
|
-
//
|
|
49
|
-
// language at counts
|
|
45
|
+
// The four count labels are plural families. i18next looks up the ONE suffix
|
|
46
|
+
// a language's rules ask for, so every pack spells out every CLDR category its
|
|
47
|
+
// language selects (`en`: `_one`/`_other`; `ru` adds `_few`/`_many`, `ar`
|
|
48
|
+
// `_zero`/`_two`/`_few`/`_many` — objectui#11432); the BASE key (no suffix)
|
|
49
|
+
// answers a call made without a count. `all-locales-key-parity.test.ts`
|
|
50
|
+
// derives the required slots from `Intl.PluralRules`, and
|
|
51
|
+
// `perm-home-namespace-3546.test.tsx` renders every language at counts
|
|
52
|
+
// 1/2/3/5/11/21/100.
|
|
50
53
|
perm: {
|
|
51
54
|
facet: {
|
|
52
55
|
none: 'None',
|
|
53
56
|
more: '+{{count}} more',
|
|
54
57
|
objects: '{{count}} objects',
|
|
55
58
|
objects_one: '{{count}} object',
|
|
59
|
+
objects_other: '{{count}} objects',
|
|
56
60
|
fields: '{{count}} field rules',
|
|
57
61
|
fields_one: '{{count}} field rule',
|
|
62
|
+
fields_other: '{{count}} field rules',
|
|
58
63
|
rls: '{{count}} RLS policies',
|
|
59
64
|
rls_one: '{{count}} RLS policy',
|
|
65
|
+
rls_other: '{{count}} RLS policies',
|
|
60
66
|
tabs: '{{count}} tab rules',
|
|
61
67
|
tabs_one: '{{count}} tab rule',
|
|
68
|
+
tabs_other: '{{count}} tab rules',
|
|
62
69
|
adminScope: 'Delegated admin configured',
|
|
63
70
|
designInStudio: 'Design in Studio →',
|
|
64
71
|
designInStudioHint: 'Design in Studio',
|
|
@@ -80,7 +87,8 @@ const en = {
|
|
|
80
87
|
selectFirst: 'Select {{fields}} first',
|
|
81
88
|
selectRecord: 'Select record',
|
|
82
89
|
recordCount: '{{count}} records',
|
|
83
|
-
|
|
90
|
+
recordCount_one: '{{count}} record',
|
|
91
|
+
recordCount_other: '{{count}} records',
|
|
84
92
|
pageOf: 'Page {{current}} of {{total}}',
|
|
85
93
|
filters: 'Filters',
|
|
86
94
|
clear: 'Clear',
|
|
@@ -94,6 +102,15 @@ const en = {
|
|
|
94
102
|
common: {
|
|
95
103
|
loading: 'Loading…',
|
|
96
104
|
save: 'Save',
|
|
105
|
+
// The SHARED "throw away the unsaved draft" verb, read by
|
|
106
|
+
// `@object-ui/components`' `ConfigPanelRenderer` footer (objectui#4750).
|
|
107
|
+
// The three older spellings stay where they are because each belongs to one
|
|
108
|
+
// surface's wording: `form.discard` is the confirm button of plugin-form's
|
|
109
|
+
// "Discard changes?" alert dialog, `console.settingsView.discard` and
|
|
110
|
+
// `console.objectView.discard` are two console view footers — and the last
|
|
111
|
+
// of those already disagrees with the other two in zh/ko/fr. This one is
|
|
112
|
+
// the shared component's, and its ten values are the majority spelling.
|
|
113
|
+
discard: 'Discard',
|
|
97
114
|
cancel: 'Cancel',
|
|
98
115
|
delete: 'Delete',
|
|
99
116
|
edit: 'Edit',
|
|
@@ -128,10 +145,12 @@ const en = {
|
|
|
128
145
|
closeChat: 'Close chat',
|
|
129
146
|
closePanel: 'Close panel',
|
|
130
147
|
resizeDrawer: 'Resize drawer',
|
|
131
|
-
// Count badge on a tab / section header.
|
|
132
|
-
//
|
|
148
|
+
// Count badge on a tab / section header. An i18next count family
|
|
149
|
+
// (objectui#11445): the badge passes `count` and i18next picks the slot
|
|
150
|
+
// each pack's CLDR rules select.
|
|
133
151
|
itemCount: '{{count}} items',
|
|
134
|
-
|
|
152
|
+
itemCount_one: '{{count}} item',
|
|
153
|
+
itemCount_other: '{{count}} items',
|
|
135
154
|
toggleSidebar: 'Toggle sidebar',
|
|
136
155
|
package: 'Package',
|
|
137
156
|
done: 'Done',
|
|
@@ -139,6 +158,16 @@ const en = {
|
|
|
139
158
|
record: 'Record',
|
|
140
159
|
retry: 'Retry',
|
|
141
160
|
printDialogHint: 'Opens your browser’s print dialog (not a PDF export)',
|
|
161
|
+
// The non-grid row ceiling's footnote (objectui#7210). Two keys because
|
|
162
|
+
// there are two conditions: a reported `total` states the fact with BOTH
|
|
163
|
+
// numbers, a missing one cannot name how many. Kept terse deliberately —
|
|
164
|
+
// this copy is eagerly loaded, and since objectui#7399 these bytes are
|
|
165
|
+
// budgeted by the `i18n-locales` chunk, not `framework`. ⛔ That ceiling's
|
|
166
|
+
// headroom is deliberately NOT restated here — it moves on every
|
|
167
|
+
// re-baseline, and the figure that was here went stale.
|
|
168
|
+
// `pnpm check:eager-closure` prints it.
|
|
169
|
+
rowCeilingNote: 'Showing the first {{shown}} of {{total}} records. Narrow the filter.',
|
|
170
|
+
rowCeilingNoteUnknownTotal: 'Showing the first {{shown}} records. Narrow the filter.',
|
|
142
171
|
},
|
|
143
172
|
actions: {
|
|
144
173
|
decisionOutput: {
|
|
@@ -150,6 +179,32 @@ const en = {
|
|
|
150
179
|
acknowledge: 'I have saved this',
|
|
151
180
|
copyAll: 'Copy all',
|
|
152
181
|
},
|
|
182
|
+
// The refusal notice for an action whose `autoTrigger` its own declared
|
|
183
|
+
// `visible` gate outranks (objectui#4191) — the deep link or host asked
|
|
184
|
+
// for it, but the author hid it on this surface.
|
|
185
|
+
notAvailableHere: '"{{action}}" is not available on the current page.',
|
|
186
|
+
// The success toast the action runner shows when no `outcomeMessages`
|
|
187
|
+
// entry applies to the answer and the action declares no `successMessage`;
|
|
188
|
+
// the server's message plays no part (objectui#11344). It is the one
|
|
189
|
+
// success-toast text the runner writes itself (objectui#10900).
|
|
190
|
+
completedSuccessfully: 'Action completed successfully',
|
|
191
|
+
// The runner's other own text (objectui#10969): the error fallbacks when no
|
|
192
|
+
// readable error message reached it, and the Undo label it hands the toast
|
|
193
|
+
// handler for an undoable success toast.
|
|
194
|
+
failed: 'Action failed',
|
|
195
|
+
parallelFailed: 'One or more parallel actions failed',
|
|
196
|
+
undo: 'Undo',
|
|
197
|
+
// The confirmation toast after that Undo has run — written by the console's
|
|
198
|
+
// two undo handlers (`useConsoleActionRuntime` and `RecordDetailView`), not
|
|
199
|
+
// by the runner (objectui#11056).
|
|
200
|
+
undone: 'Change undone',
|
|
201
|
+
// The console's global Ctrl+Z / Ctrl+Shift+Z toasts, raised by
|
|
202
|
+
// `AppContent`'s `useGlobalUndo` handlers once the operation has been
|
|
203
|
+
// undone / redone (objectui#11080). `{{description}}` is the operation's
|
|
204
|
+
// own description, passed through unchanged; the pack owns the words and
|
|
205
|
+
// the word order around it.
|
|
206
|
+
undoneOperation: 'Undo: {{description}}',
|
|
207
|
+
redoneOperation: 'Redo: {{description}}',
|
|
153
208
|
},
|
|
154
209
|
validation: {
|
|
155
210
|
required: '{{field}} is required',
|
|
@@ -172,8 +227,26 @@ const en = {
|
|
|
172
227
|
},
|
|
173
228
|
form: {
|
|
174
229
|
noPermissionToSave: "You don't have permission to save this record.",
|
|
230
|
+
// The notice a record form shows when every field is locked because the
|
|
231
|
+
// object's affordance for the form's mode is closed for this user
|
|
232
|
+
// (objectui#11000). `{{object}}` is the object's label.
|
|
233
|
+
noPermissionToCreate: "You don't have permission to create {{object}} records. The fields are read-only.",
|
|
234
|
+
noPermissionToEdit: "You don't have permission to edit {{object}} records. The fields are read-only.",
|
|
175
235
|
submitFailed: 'Could not save. Please try again.',
|
|
176
|
-
|
|
236
|
+
uploadInFlight: 'Wait for the upload to finish before saving.',
|
|
237
|
+
// The notice the record form raises when a field's own `visibleWhen` turns
|
|
238
|
+
// it invisible and the form clears the value it held (objectui#8070 names
|
|
239
|
+
// the `6a449fc49` clear). `{{fields}}` is the cleared fields' labels joined
|
|
240
|
+
// with `validation.formInvalidJoiner`. A list after a colon, so no word has
|
|
241
|
+
// to agree with how many fields were cleared.
|
|
242
|
+
clearedOnHide: 'Cleared — no longer applicable given the current values: {{fields}}',
|
|
243
|
+
// The refusal a record form raises at SUBMIT when a field's own
|
|
244
|
+
// `visibleWhen` could not be evaluated (objectui#8069, ADR-0137 D2 as ruled:
|
|
245
|
+
// the client refuses the one rule no server judges). It names the rule and
|
|
246
|
+
// the fields — `{{fields}}` is their labels joined with
|
|
247
|
+
// `validation.formInvalidJoiner` — because the fix is to the metadata, not
|
|
248
|
+
// to anything the person filling the form can type.
|
|
249
|
+
visibleWhenFaulted: "Can't submit: the visibleWhen rule of {{fields}} could not be evaluated. The rule must be fixed before this form can be submitted.",
|
|
177
250
|
removeItem: 'Remove item',
|
|
178
251
|
fieldRequired: 'This field is required',
|
|
179
252
|
invalidFormat: 'Invalid format',
|
|
@@ -188,6 +261,57 @@ const en = {
|
|
|
188
261
|
// only displace it by authoring a `description`, which makes a VISIBLE
|
|
189
262
|
// subtitle appear on every form — so the fallback has to come from here.
|
|
190
263
|
dialogDescriptionFallback: 'Complete the form fields, then submit or cancel.',
|
|
264
|
+
// The hint under a field the caller may read but not write, shown when the
|
|
265
|
+
// field declares no description of its own (objectui#11071).
|
|
266
|
+
deniedDescription: 'You do not have edit access to this field.',
|
|
267
|
+
// The master-detail form's own chrome (objectui#11071): the collection
|
|
268
|
+
// placeholder while its columns resolve, the document totals stack
|
|
269
|
+
// (`{{rate}}` is the header's tax rate), the row editor's title
|
|
270
|
+
// (`{{title}}` is the collection's authored title, or `lineItem` when it
|
|
271
|
+
// has none; `{{row}}` is the 1-based row number), its Apply button, and the
|
|
272
|
+
// sr-only description of the dialog that hosts the form. The verbs `Add`,
|
|
273
|
+
// `Close` and `Saving…` come from `detail.add`, `common.close` and
|
|
274
|
+
// `detail.saving`.
|
|
275
|
+
masterDetail: {
|
|
276
|
+
loadingColumns: 'Loading columns…',
|
|
277
|
+
subtotal: 'Subtotal',
|
|
278
|
+
tax: 'Tax ({{rate}}%)',
|
|
279
|
+
total: 'Total',
|
|
280
|
+
lineItem: 'Line item',
|
|
281
|
+
rowTitle: '{{title}} — row {{row}}',
|
|
282
|
+
applyRow: 'Apply',
|
|
283
|
+
editorDescription: 'Enter the record and its line items, then save.',
|
|
284
|
+
// A collection's configuration hints (objectui#11160): no `childObject`
|
|
285
|
+
// (the twin of `lineItems.noChildObject`, which names the panel), a
|
|
286
|
+
// child schema that failed to load, and no lookup or master_detail
|
|
287
|
+
// field on the child that references the parent. `{{property}}` is a
|
|
288
|
+
// property name and `{{object}}` / `{{parent}}` are object names; each
|
|
289
|
+
// is rendered as code and never translated. `lookup` and
|
|
290
|
+
// `master_detail` are field type names, so every pack keeps them as
|
|
291
|
+
// written.
|
|
292
|
+
noChildObject: 'This collection has no child object configured: set {{property}} to the object whose rows it lists.',
|
|
293
|
+
schemaUnavailable: 'Could not load the schema of {{object}}, so this collection has no columns to show. Check that the object exists and is readable, then reload.',
|
|
294
|
+
noRelationshipField: 'Could not work out how {{object}} links to {{parent}}: no lookup or master_detail field on it references the parent. Set {{property}} on this collection to the field that holds the parent record.',
|
|
295
|
+
},
|
|
296
|
+
// The record page's `record:line_items` panel (objectui#11131): its
|
|
297
|
+
// title when the author declared none. Its Save / Saving… button reads
|
|
298
|
+
// `common.save` / `detail.saving`. `MasterDetailForm` reads `title` too,
|
|
299
|
+
// for a collection that authors no heading (objectui#11145).
|
|
300
|
+
//
|
|
301
|
+
// The rest is the panel's own states (objectui#11145): no parent record
|
|
302
|
+
// bound yet, rows held for another parent, and the two fallbacks for a
|
|
303
|
+
// failed load or save, shown when the server sent no message of its own.
|
|
304
|
+
// Its loading line reads `common.loading`. `noChildObject` is the config
|
|
305
|
+
// hint for a panel with no `childObject`: `{{property}}` is filled with
|
|
306
|
+
// the property name, rendered as code and never translated.
|
|
307
|
+
lineItems: {
|
|
308
|
+
title: 'Line Items',
|
|
309
|
+
saveRecordFirst: 'Save the record first to add line items.',
|
|
310
|
+
notLoaded: 'This record’s line items have not been loaded.',
|
|
311
|
+
loadFailed: 'Failed to load line items',
|
|
312
|
+
saveFailed: 'Failed to save line items',
|
|
313
|
+
noChildObject: 'This panel has no child object configured: set {{property}} to the object whose rows it lists.',
|
|
314
|
+
},
|
|
191
315
|
keepEditing: 'Keep editing',
|
|
192
316
|
discard: 'Discard',
|
|
193
317
|
conflictTitle: 'Save conflict',
|
|
@@ -205,6 +329,26 @@ const en = {
|
|
|
205
329
|
createSuccess: '{{object}} created successfully',
|
|
206
330
|
updateSuccess: '{{object}} updated successfully',
|
|
207
331
|
deleteSuccess: '{{object}} deleted successfully',
|
|
332
|
+
// plugin-form's own feedback chrome (objectui#11039): the success toast
|
|
333
|
+
// a form raises when the author declared no `successMessage` (`created`
|
|
334
|
+
// after a create, `saved` after an edit), the master-detail form's edit
|
|
335
|
+
// toast when the form has a `title` (`{{title}}` is that title), and the
|
|
336
|
+
// console form page's toast after a submit. An authored message always
|
|
337
|
+
// wins; these are only the defaults. The form's loading line and its
|
|
338
|
+
// thank-you panel read `publicForm.loading` / `publicForm.thankYouTitle` /
|
|
339
|
+
// `publicForm.thankYouMessage`, which say the same thing.
|
|
340
|
+
created: 'Created',
|
|
341
|
+
saved: 'Saved',
|
|
342
|
+
savedNamed: '{{title}} saved',
|
|
343
|
+
submitted: 'Submitted',
|
|
344
|
+
// The heading of the panel a form shows when its object schema or its
|
|
345
|
+
// record could not be loaded; the error's own message follows it.
|
|
346
|
+
errorLoading: 'Error loading form',
|
|
347
|
+
// Rides the success toast when a DECLARED `navigateOnSuccess` produced no
|
|
348
|
+
// destination (objectui#5034): the write succeeded, the declared
|
|
349
|
+
// navigation did not happen. `navigateOnSuccess` is the metadata key's
|
|
350
|
+
// name, so every pack keeps it as written.
|
|
351
|
+
navigateRefused: 'The `navigateOnSuccess` destination declared for this form was refused, so the navigation did not happen.',
|
|
208
352
|
fullscreen: {
|
|
209
353
|
title: 'Edit text',
|
|
210
354
|
description: 'Edit the full text value, then save or cancel your changes.',
|
|
@@ -216,6 +360,8 @@ const en = {
|
|
|
216
360
|
fields: {
|
|
217
361
|
relativeDate: {
|
|
218
362
|
overdue: 'Overdue {{count}}d',
|
|
363
|
+
overdue_one: 'Overdue {{count}}d',
|
|
364
|
+
overdue_other: 'Overdue {{count}}d',
|
|
219
365
|
},
|
|
220
366
|
file: {
|
|
221
367
|
dragDropHere: 'Drag & drop files here',
|
|
@@ -232,6 +378,7 @@ const en = {
|
|
|
232
378
|
remove: 'Remove {{name}}',
|
|
233
379
|
exceedsMaxSize: '"{{name}}" exceeds max size ({{max}} MB)',
|
|
234
380
|
uploadFailed: 'Failed to upload "{{name}}": {{error}}',
|
|
381
|
+
uploadIncomplete: 'Upload of "{{name}}" did not complete: no file id was returned, so nothing was saved',
|
|
235
382
|
},
|
|
236
383
|
image: {
|
|
237
384
|
upload: 'Upload image',
|
|
@@ -276,6 +423,9 @@ const en = {
|
|
|
276
423
|
selectBusinessUnit: 'Select a business unit',
|
|
277
424
|
selectPosition: 'Select a position',
|
|
278
425
|
selectUnitAndSubordinates: 'Select a business unit',
|
|
426
|
+
selectField: 'Select a user field',
|
|
427
|
+
noUserFields: 'No user fields on this object',
|
|
428
|
+
fieldNotUserTyped: '{{name}} — not a user field',
|
|
279
429
|
},
|
|
280
430
|
filterCondition: {
|
|
281
431
|
selectObjectFirst: 'Select an object first.',
|
|
@@ -286,11 +436,112 @@ const en = {
|
|
|
286
436
|
editAsJson: 'Edit as JSON',
|
|
287
437
|
useVisualBuilder: 'Use visual builder',
|
|
288
438
|
},
|
|
439
|
+
// objectui#6755 — a widget's OWN refusal sentence: `ObjectField`'s
|
|
440
|
+
// unparsable JSON draft, and `LocationField`'s format and range refusals
|
|
441
|
+
// (objectui#6716 / #6714). They were string literals in the widgets, so a
|
|
442
|
+
// zh / ja / ar user who mistyped a coordinate or a JSON blob was told why in
|
|
443
|
+
// English inside a form whose every other word was translated.
|
|
444
|
+
//
|
|
445
|
+
// KEYED, where objectui#4028 DROPPED the five address placeholders in the
|
|
446
|
+
// namespace below — and the difference is what that decision's own comment
|
|
447
|
+
// records about them: "The right example is a function of the address's
|
|
448
|
+
// COUNTRY, not the reader's language", and "Each box here already has a
|
|
449
|
+
// visible label naming exactly what it wants". Neither reaches a refusal
|
|
450
|
+
// sentence: nothing else on the screen says why the edit was refused, and
|
|
451
|
+
// what that sentence must say IS a function of the reader's language. What
|
|
452
|
+
// #4028 does establish for both is the COST — ten pack entries per key,
|
|
453
|
+
// bound from then on by `check:i18n-drift` — and the 2026-08-29 maintainer
|
|
454
|
+
// ruling accepted that cost for these three sentences.
|
|
455
|
+
//
|
|
456
|
+
// Values are byte-identical to the literals they replace (`FIELD_DEFAULTS`
|
|
457
|
+
// in `packages/fields/src/widgets/useFieldTranslation.ts` carries the same
|
|
458
|
+
// three), so English and provider-less rendering are unchanged.
|
|
459
|
+
//
|
|
460
|
+
// `{{detail}}` is the SPEC's own complaint about the refused pair.
|
|
461
|
+
// `LocationField` refuses to restate `LocationValueSchema`'s bounds — a
|
|
462
|
+
// hand-copied range is a second contract — so this key translates the frame
|
|
463
|
+
// and interpolates whatever the schema said.
|
|
464
|
+
object: {
|
|
465
|
+
invalidJson: 'Invalid JSON',
|
|
466
|
+
},
|
|
467
|
+
location: {
|
|
468
|
+
refusedFormat: 'Not saved: enter a latitude, longitude pair (example: 30.2741, 120.1551).',
|
|
469
|
+
refusedRange: 'Not saved: {{detail}}',
|
|
470
|
+
latitude: 'latitude',
|
|
471
|
+
longitude: 'longitude',
|
|
472
|
+
refusedResidueOne: 'Not saved: {{name}} "{{text}}" is not a number. Enter plain decimals (example: 30.2741, 120.1551).',
|
|
473
|
+
refusedResidue: 'Not saved: {{name}} "{{text}}" and {{otherName}} "{{otherText}}" are not numbers. Enter plain decimals (example: 30.2741, 120.1551).',
|
|
474
|
+
},
|
|
475
|
+
// objectui#8148 — the FIFTH refusal sentence of objectui#6755's class, and
|
|
476
|
+
// the only SHARED one. The four above are each ONE widget's; this one is
|
|
477
|
+
// produced by `numberBadInput.tsx` for `NumberField`, `CurrencyField`,
|
|
478
|
+
// `PercentField` and both of `GeolocationField`'s boxes. That last is the
|
|
479
|
+
// sharpest case: it sits beside `LocationField`, whose refusals are keyed
|
|
480
|
+
// right above, so two adjacent coordinate widgets refused bad input in two
|
|
481
|
+
// different languages on the same form.
|
|
482
|
+
//
|
|
483
|
+
// ⭐ `{{example}}` is a HOLE, and that is what keeps decimal numerals out
|
|
484
|
+
// of every pack. Five different values reach this one sentence (`1234`,
|
|
485
|
+
// `1234.56`, `12.5`, `30.2741`, `120.1551`), so keying the example per
|
|
486
|
+
// widget would be five keys times ten packs — and each pack would then
|
|
487
|
+
// hold a decimal it could legitimately re-punctuate, where `1234,56` reads
|
|
488
|
+
// as the `latitude, longitude` PAIR `refusedFormat` above asks for. The
|
|
489
|
+
// widget fills the hole in ASCII; no pack spells a digit.
|
|
490
|
+
//
|
|
491
|
+
// The English value is byte-identical to the literal it replaces
|
|
492
|
+
// (`FIELD_DEFAULTS` in `packages/fields/src/widgets/useFieldTranslation.ts`
|
|
493
|
+
// carries the same one), so English and provider-less rendering are
|
|
494
|
+
// unchanged.
|
|
495
|
+
// objectui#10567 — the editable date-only face's notice for a stored value
|
|
496
|
+
// written on a day that does not exist, the date-only sibling of
|
|
497
|
+
// `dateTime.impossibleDay` below: an `<input type="date">` can only paint
|
|
498
|
+
// such a value blank, so the widget names the stored string beside it.
|
|
499
|
+
// `FIELD_DEFAULTS` in `packages/fields/src/widgets/useFieldTranslation.ts`
|
|
500
|
+
// carries the same English value for provider-less rendering.
|
|
501
|
+
date: {
|
|
502
|
+
impossibleDay: 'The stored value "{{value}}" is not a real date. Pick a date to replace it.',
|
|
503
|
+
},
|
|
504
|
+
// objectui#10474 — the editable date-time face's notice for a stored value
|
|
505
|
+
// written on a day that does not exist. The `datetime-local` control can
|
|
506
|
+
// only paint such a value blank, so the widget names the stored string
|
|
507
|
+
// beside it; a blank control alone would hide it (objectui#3127).
|
|
508
|
+
// `FIELD_DEFAULTS` in `packages/fields/src/widgets/useFieldTranslation.ts`
|
|
509
|
+
// carries the same English value for provider-less rendering.
|
|
510
|
+
dateTime: {
|
|
511
|
+
impossibleDay: 'The stored value "{{value}}" is not a real date. Pick a date and time to replace it.',
|
|
512
|
+
},
|
|
513
|
+
number: {
|
|
514
|
+
badInput: 'Not saved: the text in this box is not a number. Enter a plain decimal (example: {{example}}).',
|
|
515
|
+
},
|
|
289
516
|
// objectui#3342 — the tags widget's input hint, shown while the tag list
|
|
290
517
|
// is empty. The author-declared `field.placeholder` always wins over this.
|
|
291
518
|
tags: {
|
|
292
519
|
placeholder: 'Type and press Enter to add…',
|
|
293
520
|
},
|
|
521
|
+
// objectui#4028 — `AddressField`'s five sub-labels, previously English
|
|
522
|
+
// string literals with no key at all: on a Chinese console every address
|
|
523
|
+
// field showed five English words in the middle of an otherwise fully
|
|
524
|
+
// translated form, and an app had NO way to reach them. The parts are not
|
|
525
|
+
// fields on the object (`billing_address` is a single `address` column),
|
|
526
|
+
// so there was nothing for a translation bundle to key on and no
|
|
527
|
+
// `subLabels` property to declare — the only workaround left was to stop
|
|
528
|
+
// using `Field.address()` and author five text fields, losing the
|
|
529
|
+
// structured value, geocoding and map view.
|
|
530
|
+
//
|
|
531
|
+
// Values are byte-identical to the literals they replace, so English and
|
|
532
|
+
// provider-less rendering are unchanged (`FIELD_DEFAULTS` in
|
|
533
|
+
// `packages/fields/src/widgets/useFieldTranslation.ts` carries the same
|
|
534
|
+
// five, which is what a host with no `I18nProvider` renders).
|
|
535
|
+
//
|
|
536
|
+
// The five INPUT PLACEHOLDERS that sat next to these labels are gone
|
|
537
|
+
// rather than keyed — see the widget for that measurement.
|
|
538
|
+
address: {
|
|
539
|
+
street: 'Street Address',
|
|
540
|
+
city: 'City',
|
|
541
|
+
state: 'State / Province',
|
|
542
|
+
postalCode: 'ZIP / Postal Code',
|
|
543
|
+
country: 'Country',
|
|
544
|
+
},
|
|
294
545
|
// objectui#3406 — the accessible sentence of the textarea character
|
|
295
546
|
// counter, rendered only when the field declares `maxLength`. The visible
|
|
296
547
|
// text is `{count}/{max}` digits and needs no locale. ONE interpolated key
|
|
@@ -312,6 +563,26 @@ const en = {
|
|
|
312
563
|
characterCount: 'Character count: {{count}} of {{max}}',
|
|
313
564
|
charactersRemaining: 'Characters remaining: {{count}}',
|
|
314
565
|
},
|
|
566
|
+
// objectui#11131 — the line-items grid's default chrome (`GridField`):
|
|
567
|
+
// its Add button, the read-only grid's empty state, and the list-mode
|
|
568
|
+
// grid's empty state. An authored `add_label` still wins over `addLine`,
|
|
569
|
+
// and it fills the `{{label}}` hole (`detail.add` when none is authored).
|
|
570
|
+
//
|
|
571
|
+
// objectui#11145 — the rest of that chrome: the column chooser's heading,
|
|
572
|
+
// the computed cell's tooltip, and the row actions. Each row action has
|
|
573
|
+
// one key, read by both its `aria-label` and its `title`. The chooser's
|
|
574
|
+
// button reads `table.columns`, the footer `form.masterDetail.total` and
|
|
575
|
+
// the drag handle `view.dragToReorder`.
|
|
576
|
+
grid: {
|
|
577
|
+
addLine: 'Add line',
|
|
578
|
+
noItems: 'No items',
|
|
579
|
+
noItemsAddHint: 'No items yet — click “{{label}}” to begin.',
|
|
580
|
+
optionalColumns: 'Optional columns',
|
|
581
|
+
computed: 'Computed',
|
|
582
|
+
openRow: 'Open row',
|
|
583
|
+
duplicateRow: 'Duplicate row',
|
|
584
|
+
removeRow: 'Remove row',
|
|
585
|
+
},
|
|
315
586
|
},
|
|
316
587
|
table: {
|
|
317
588
|
rowsPerPage: 'Rows per page',
|
|
@@ -340,8 +611,12 @@ const en = {
|
|
|
340
611
|
open: 'Open',
|
|
341
612
|
search: 'Search…',
|
|
342
613
|
modified: '{{count}} row modified',
|
|
614
|
+
modified_one: '{{count}} row modified',
|
|
615
|
+
modified_other: '{{count}} rows modified',
|
|
343
616
|
saveFailed: 'Save failed',
|
|
344
617
|
selected: '{{count}} selected',
|
|
618
|
+
selected_one: '{{count}} selected',
|
|
619
|
+
selected_other: '{{count}} selected',
|
|
345
620
|
edit: 'Edit',
|
|
346
621
|
delete: 'Delete',
|
|
347
622
|
},
|
|
@@ -358,9 +633,13 @@ const en = {
|
|
|
358
633
|
openRecord: 'Open record',
|
|
359
634
|
openMenu: 'Open menu',
|
|
360
635
|
bulkSelected: '{{count}} selected',
|
|
636
|
+
bulkSelected_one: '{{count}} selected',
|
|
637
|
+
bulkSelected_other: '{{count}} selected',
|
|
361
638
|
bulkSelectedAllMatches: '{{count}} selected (all matches)',
|
|
362
639
|
bulkClear: 'Clear',
|
|
363
640
|
bulkAllOnPage: 'All {{count}} on this page are selected.',
|
|
641
|
+
bulkAllOnPage_one: '{{count}} record on this page is selected.',
|
|
642
|
+
bulkAllOnPage_other: 'All {{count}} on this page are selected.',
|
|
364
643
|
bulkSelectAllMatching: 'Select all {{count}} matching',
|
|
365
644
|
bulkAllMatchingSelected: 'All {{count}} matching records are selected.',
|
|
366
645
|
rowHeight: 'Row height: {{mode}}',
|
|
@@ -368,6 +647,14 @@ const en = {
|
|
|
368
647
|
yes: 'Yes',
|
|
369
648
|
no: 'No',
|
|
370
649
|
systemFields: 'System',
|
|
650
|
+
// objectui#10881 — the grouped grid's two refusals: over a data source
|
|
651
|
+
// that cannot answer the group header query, and over rows a host
|
|
652
|
+
// handed in while declaring them one page of more. `queryGroupHeaders`
|
|
653
|
+
// is the member's name and stays untranslated.
|
|
654
|
+
grouping: {
|
|
655
|
+
needsHeaderQuery: 'This view is grouped, but its data source does not implement queryGroupHeaders, so the groups cannot be counted. Remove the grouping to show the records.',
|
|
656
|
+
needsWholeRows: 'Grouping needs every record, but this grid was handed one page of them, so the groups cannot be counted. Hand in every record, or let the grid fetch them from a data source that implements queryGroupHeaders.',
|
|
657
|
+
},
|
|
371
658
|
// Column-footer aggregate prefixes, keyed by the spec's `ColumnSummary`
|
|
372
659
|
// vocabulary (objectui#4024). The footer already formatted its NUMBER
|
|
373
660
|
// through the locale-aware formatter and then put a hardcoded English
|
|
@@ -413,8 +700,10 @@ const en = {
|
|
|
413
700
|
dragDrop: 'Drag & drop a CSV or Excel file here, or click to browse',
|
|
414
701
|
browseFiles: 'Browse Files',
|
|
415
702
|
downloadTemplate: 'Download template',
|
|
416
|
-
downloadTemplateHint: 'Get
|
|
703
|
+
downloadTemplateHint: 'Get an Excel file of the columns you can import (required fields marked *), with instructions for filling it in.',
|
|
417
704
|
templateFileName: '{{object}}-import-template',
|
|
705
|
+
templateDownloadFailed: 'Could not download the template. Please try again.',
|
|
706
|
+
templateNotPermitted: 'You do not have permission to create records of this object, so its import template is not available.',
|
|
418
707
|
parsing: 'Parsing…',
|
|
419
708
|
pasteHint: 'or paste (Ctrl/⌘+V) rows copied from Excel or Google Sheets',
|
|
420
709
|
legacyXls: 'Legacy .xls files aren\'t supported — please re-save as .xlsx.',
|
|
@@ -440,6 +729,8 @@ const en = {
|
|
|
440
729
|
typeMismatch: 'Looks like {{type}}',
|
|
441
730
|
autoMatched: 'Auto-matched',
|
|
442
731
|
autoMatchedSummary: 'Auto-matched {{count}} column(s) — review and adjust below.',
|
|
732
|
+
autoMatchedSummary_one: 'Auto-matched {{count}} column — review and adjust below.',
|
|
733
|
+
autoMatchedSummary_other: 'Auto-matched {{count}} columns — review and adjust below.',
|
|
443
734
|
confidence: {
|
|
444
735
|
high: 'High confidence',
|
|
445
736
|
medium: 'Medium confidence',
|
|
@@ -458,7 +749,11 @@ const en = {
|
|
|
458
749
|
mapped: 'Mapped',
|
|
459
750
|
skipped: 'Skipped',
|
|
460
751
|
rowsWithErrors: '{{count}} row(s) with errors',
|
|
752
|
+
rowsWithErrors_one: '{{count}} row with errors',
|
|
753
|
+
rowsWithErrors_other: '{{count}} rows with errors',
|
|
461
754
|
rowsCorrected: '{{count}} row(s) corrected',
|
|
755
|
+
rowsCorrected_one: '{{count}} row corrected',
|
|
756
|
+
rowsCorrected_other: '{{count}} rows corrected',
|
|
462
757
|
clickToFix: '— click a highlighted cell to fix it inline.',
|
|
463
758
|
showingRows: 'Showing {{shown}} of {{total}} rows',
|
|
464
759
|
importing: 'Importing… {{progress}}%',
|
|
@@ -469,12 +764,20 @@ const en = {
|
|
|
469
764
|
cancelImport: 'Cancel import',
|
|
470
765
|
importCancelled: 'Import cancelled',
|
|
471
766
|
resultsTruncated: 'Showing the first {{count}} row results (of {{total}}).',
|
|
767
|
+
resultsTruncated_one: 'Showing the first {{count}} row result (of {{total}}).',
|
|
768
|
+
resultsTruncated_other: 'Showing the first {{count}} row results (of {{total}}).',
|
|
472
769
|
importComplete: 'Import Complete',
|
|
473
770
|
imported: '{{count}} imported',
|
|
474
771
|
createdCount: '{{count}} created',
|
|
772
|
+
createdCount_one: '{{count}} created',
|
|
773
|
+
createdCount_other: '{{count}} created',
|
|
475
774
|
updatedCount: '{{count}} updated',
|
|
775
|
+
updatedCount_one: '{{count}} updated',
|
|
776
|
+
updatedCount_other: '{{count}} updated',
|
|
476
777
|
skippedCount: '{{count}} skipped',
|
|
477
778
|
moreErrors: '…and {{count}} more errors',
|
|
779
|
+
moreErrors_one: '…and {{count}} more error',
|
|
780
|
+
moreErrors_other: '…and {{count}} more errors',
|
|
478
781
|
downloadFailed: 'Download failed rows',
|
|
479
782
|
options: 'Import options',
|
|
480
783
|
writeMode: 'When a row matches an existing record',
|
|
@@ -522,6 +825,8 @@ const en = {
|
|
|
522
825
|
historyColResult: 'Result',
|
|
523
826
|
historyColTime: 'When',
|
|
524
827
|
errorCount: '{{count}} errors',
|
|
828
|
+
errorCount_one: '{{count}} error',
|
|
829
|
+
errorCount_other: '{{count}} errors',
|
|
525
830
|
undoImport: 'Undo import',
|
|
526
831
|
undoing: 'Undoing…',
|
|
527
832
|
undoConfirm: 'Undo this import? Records it created will be deleted and records it updated will be restored to their previous values.',
|
|
@@ -538,6 +843,8 @@ const en = {
|
|
|
538
843
|
next: 'Next',
|
|
539
844
|
close: 'Close',
|
|
540
845
|
importNRows: 'Import {{count}} Rows',
|
|
846
|
+
importNRows_one: 'Import {{count}} Row',
|
|
847
|
+
importNRows_other: 'Import {{count}} Rows',
|
|
541
848
|
importingProgress: 'Importing…',
|
|
542
849
|
required: 'Required',
|
|
543
850
|
invalidType: 'Invalid {{type}}',
|
|
@@ -549,9 +856,13 @@ const en = {
|
|
|
549
856
|
},
|
|
550
857
|
bulk: {
|
|
551
858
|
confirmDefault: 'This will apply to {{count}} record(s).',
|
|
859
|
+
confirmDefault_one: 'This will apply to {{count}} record.',
|
|
860
|
+
confirmDefault_other: 'This will apply to {{count}} records.',
|
|
552
861
|
overLimit: 'Selection ({{count}}) exceeds the action limit ({{limit}}). Reduce the selection to proceed.',
|
|
553
862
|
affectedRecords: 'Affected records ({{count}}):',
|
|
554
863
|
skippedIneligible: '{{count}} selected record(s) are not eligible for this action and will be skipped.',
|
|
864
|
+
skippedIneligible_one: '{{count}} selected record is not eligible for this action and will be skipped.',
|
|
865
|
+
skippedIneligible_other: '{{count}} selected records are not eligible for this action and will be skipped.',
|
|
555
866
|
rowFallback: 'Row {{index}}',
|
|
556
867
|
andMore: '\u2026 and {{count}} more',
|
|
557
868
|
processed: '{{count}} / {{total}} processed',
|
|
@@ -569,7 +880,6 @@ const en = {
|
|
|
569
880
|
undo: 'Undo',
|
|
570
881
|
undoing: 'Undoing\u2026',
|
|
571
882
|
done: 'Done',
|
|
572
|
-
selectPlaceholder: 'Select\u2026',
|
|
573
883
|
loading: 'Loading\u2026',
|
|
574
884
|
},
|
|
575
885
|
},
|
|
@@ -578,16 +888,43 @@ const en = {
|
|
|
578
888
|
month: 'Month',
|
|
579
889
|
week: 'Week',
|
|
580
890
|
day: 'Day',
|
|
581
|
-
agenda: 'Agenda',
|
|
582
891
|
allDay: 'All Day',
|
|
583
|
-
noEvents: 'No events',
|
|
584
892
|
newEvent: 'New event',
|
|
585
893
|
moreEvents: '+{{count}} more',
|
|
894
|
+
unscheduled: 'Unscheduled ({{count}})',
|
|
895
|
+
loading: 'Loading calendar…',
|
|
896
|
+
loadError: 'Error: {{message}}',
|
|
897
|
+
configRequired: 'Calendar configuration required. Please specify startDateField, the calendar\'s one required key; the event title resolves without titleField.',
|
|
898
|
+
configRequiredHint: 'It belongs on the view\'s calendar block. An interface page has no calendar slot of its own: point its sourceView at a view that declares one.',
|
|
899
|
+
eventDetails: 'Event Details',
|
|
900
|
+
pullToRefresh: 'Pull to refresh',
|
|
901
|
+
refreshing: 'Refreshing…',
|
|
902
|
+
onDate: 'On {{date}}',
|
|
903
|
+
eventTitle: 'Title',
|
|
904
|
+
eventTitlePlaceholder: 'What\'s this event about?',
|
|
905
|
+
creating: 'Creating…',
|
|
906
|
+
titleRequired: 'Title is required',
|
|
907
|
+
a11y: {
|
|
908
|
+
region: 'Calendar',
|
|
909
|
+
grid: 'Calendar grid',
|
|
910
|
+
goToToday: 'Go to today',
|
|
911
|
+
previousPeriod: 'Previous period',
|
|
912
|
+
nextPeriod: 'Next period',
|
|
913
|
+
currentDate: 'Current date: {{date}}',
|
|
914
|
+
dayCell: '{{date}}, {{count}} events',
|
|
915
|
+
dayCell_one: '{{date}}, {{count}} event',
|
|
916
|
+
dayCell_other: '{{date}}, {{count}} events',
|
|
917
|
+
resizeEventEnd: 'Resize event end',
|
|
918
|
+
resizeEventEndHint: 'Drag to change end date',
|
|
919
|
+
resizeStart: 'Resize start',
|
|
920
|
+
resizeEnd: 'Resize end',
|
|
921
|
+
},
|
|
586
922
|
},
|
|
587
923
|
list: {
|
|
588
924
|
loading: 'Loading records…',
|
|
589
925
|
recordCount: '{{count}} records',
|
|
590
|
-
|
|
926
|
+
recordCount_one: '{{count}} record',
|
|
927
|
+
recordCount_other: '{{count}} records',
|
|
591
928
|
addRecord: 'Add record',
|
|
592
929
|
tabs: 'Tabs',
|
|
593
930
|
allRecords: 'All Records',
|
|
@@ -657,7 +994,7 @@ const en = {
|
|
|
657
994
|
hideFieldsTitle: 'Hide Fields',
|
|
658
995
|
dataLimitReached: 'Showing first {{limit}} records. More data may be available.',
|
|
659
996
|
viewSettings: 'View settings',
|
|
660
|
-
viewSettingsHint: 'Grouping, color, density, and visible fields.',
|
|
997
|
+
viewSettingsHint: 'Grouping, color, density, and visible fields. Applies to everyone who uses this view.',
|
|
661
998
|
addGroup: 'Add group field',
|
|
662
999
|
collapsedByDefault: 'Collapsed by default',
|
|
663
1000
|
removeGroup: 'Remove',
|
|
@@ -722,6 +1059,17 @@ const en = {
|
|
|
722
1059
|
},
|
|
723
1060
|
gantt: {
|
|
724
1061
|
rowLabel: 'Items',
|
|
1062
|
+
unusableRange: {
|
|
1063
|
+
malformedDate: 'Unusable gantt date range — {{path}} is {{value}}, which is not a valid date. Every gantt date has to parse: the startDate and endDate on every row item, plus any minDate / maxDate pinned on the schema.',
|
|
1064
|
+
malformedRow: 'Unusable gantt rows — {{path}} is {{value}}, which is not a row shape. A gantt draws items as a list of rows, every row as an object with a label and its own items, and every row\'s items as a list of bars; a null, a number, a string or a plain object in any of those places cannot be drawn.',
|
|
1065
|
+
inverted: 'Unusable gantt date range — minDate {{minDate}} is after maxDate {{maxDate}}. A pinned minDate / maxDate overrides the range computed from the rows, so this axis has no columns and no bar can be placed on it; swap the two values.',
|
|
1066
|
+
},
|
|
1067
|
+
},
|
|
1068
|
+
unsupported: {
|
|
1069
|
+
objectBoundGantt: 'Unsupported variant "gantt" — an object-bound timeline renders the feed variants ({{variants}}). Gantt needs literal rows, each with its own nested items, so the gantt axis (scale) has no effect here.',
|
|
1070
|
+
},
|
|
1071
|
+
unconfigured: {
|
|
1072
|
+
noDateAxis: 'Timeline date axis required — this view declares no date field, and an object-bound timeline will not invent one. Declare one of: {{fields}}. The first is the spec spelling; the rest are legacy aliases.',
|
|
725
1073
|
},
|
|
726
1074
|
},
|
|
727
1075
|
gantt: {
|
|
@@ -767,6 +1115,7 @@ const en = {
|
|
|
767
1115
|
},
|
|
768
1116
|
aria: {
|
|
769
1117
|
taskList: 'Task list',
|
|
1118
|
+
refreshing: 'Refreshing…',
|
|
770
1119
|
},
|
|
771
1120
|
tooltip: {
|
|
772
1121
|
days: 'd',
|
|
@@ -812,13 +1161,19 @@ const en = {
|
|
|
812
1161
|
conflict: {
|
|
813
1162
|
title: 'Schedule conflict',
|
|
814
1163
|
body: 'This move conflicts with dependency constraints. Auto-reschedule {{count}} affected task(s)?',
|
|
1164
|
+
body_one: 'This move conflicts with dependency constraints. Auto-reschedule {{count}} affected task?',
|
|
1165
|
+
body_other: 'This move conflicts with dependency constraints. Auto-reschedule {{count}} affected tasks?',
|
|
815
1166
|
confirm: 'Auto-reschedule',
|
|
816
1167
|
cancel: 'Keep as is',
|
|
817
1168
|
},
|
|
818
1169
|
autoScheduleDlg: {
|
|
819
1170
|
title: 'Auto-schedule',
|
|
820
1171
|
body: 'Shift {{count}} task(s) later to satisfy dependency links?',
|
|
1172
|
+
body_one: 'Shift {{count}} task later to satisfy dependency links?',
|
|
1173
|
+
body_other: 'Shift {{count}} tasks later to satisfy dependency links?',
|
|
821
1174
|
skipped: '{{count}} locked task(s) also violate links and were skipped.',
|
|
1175
|
+
skipped_one: '{{count}} locked task also violates links and was skipped.',
|
|
1176
|
+
skipped_other: '{{count}} locked tasks also violate links and were skipped.',
|
|
822
1177
|
confirm: 'Apply',
|
|
823
1178
|
cancel: 'Cancel',
|
|
824
1179
|
none: 'All dependencies satisfied — nothing to reschedule.',
|
|
@@ -875,6 +1230,7 @@ const en = {
|
|
|
875
1230
|
tabActionsFor: 'View actions for {{name}}',
|
|
876
1231
|
readonlyAriaLabel: 'Read-only view',
|
|
877
1232
|
readonlyTooltip: 'System view — defined in code, read-only.',
|
|
1233
|
+
malformedFilter: 'This view’s filter is malformed, so no records are shown: the {{subject}} condition cannot be applied.',
|
|
878
1234
|
},
|
|
879
1235
|
detail: {
|
|
880
1236
|
back: 'Back',
|
|
@@ -890,6 +1246,9 @@ const en = {
|
|
|
890
1246
|
writeStrippedTitle: 'Saved — but some fields did not take effect',
|
|
891
1247
|
writeStrippedReadonly: 'Read-only, so it did not take effect: {{fields}}',
|
|
892
1248
|
writeStrippedByState: "Not editable in this record's current state, so it did not take effect: {{fields}}",
|
|
1249
|
+
writeStrippedPrimaryKey: "The record's identifier cannot be changed by a save, so it did not take effect: {{fields}}",
|
|
1250
|
+
writeStrippedComputed: 'Calculated by the server from a formula, so the value sent did not take effect: {{fields}}',
|
|
1251
|
+
writeStrippedUnknownReason: 'Not applied by the server: {{fields}}',
|
|
893
1252
|
approvalPendingEditable: 'In approval · editable',
|
|
894
1253
|
approvalPendingTooltip: 'This record has a pending approval request; this step still allows editing',
|
|
895
1254
|
approvalProgress: 'Approvals — {{got}} of {{need}}',
|
|
@@ -902,7 +1261,21 @@ const en = {
|
|
|
902
1261
|
cancelApprovalTooltipUnlocked: 'Recall the pending approval request',
|
|
903
1262
|
cancelApprovalFailed: 'Failed to recall approval',
|
|
904
1263
|
cancelApprovalUnavailable: 'Recalling approvals is not supported on this data source',
|
|
1264
|
+
// objectui#5916 — `record:path` stage state in the ACCESSIBLE NAME.
|
|
1265
|
+
// Each stage is a `role="listitem"`, which is name-from-AUTHOR only, so
|
|
1266
|
+
// visually-hidden text inside it computes to an EMPTY name; these compose
|
|
1267
|
+
// the stage's own (already picklist-localized) label with its state into the
|
|
1268
|
+
// `aria-label`. The ✓/✗ glyphs stay `aria-hidden` decoration.
|
|
1269
|
+
pathLabel: 'Record path',
|
|
1270
|
+
pathStageCompleted: '{{stage}}, completed',
|
|
1271
|
+
pathStageCurrent: '{{stage}}, current stage',
|
|
1272
|
+
pathStageUpcoming: '{{stage}}, upcoming',
|
|
1273
|
+
pathStageLostCurrent: '{{stage}}, closed lost, current stage',
|
|
1274
|
+
pathStageLostUpcoming: '{{stage}}, closed lost, not reached',
|
|
1275
|
+
pathStageWonUpcoming: '{{stage}}, goal stage, not reached',
|
|
905
1276
|
linkCopied: 'Link copied to clipboard',
|
|
1277
|
+
commentFailed: 'Your comment was not posted. Nothing was saved — please try again.',
|
|
1278
|
+
reactionFailed: 'Your reaction was not saved. Please try again.',
|
|
906
1279
|
linkCopyFailed: 'Failed to copy link',
|
|
907
1280
|
cancel: 'Cancel',
|
|
908
1281
|
cancelEdit: 'Discard changes',
|
|
@@ -929,7 +1302,8 @@ const en = {
|
|
|
929
1302
|
pageHeaderActions: 'Page header actions',
|
|
930
1303
|
emojiPicker: 'Emoji picker',
|
|
931
1304
|
reactionCount: '{{emoji}} {{count}} reactions',
|
|
932
|
-
|
|
1305
|
+
reactionCount_one: '{{emoji}} {{count}} reaction',
|
|
1306
|
+
reactionCount_other: '{{emoji}} {{count}} reactions',
|
|
933
1307
|
// Record-overlay chrome (objectstack#5506). `recordDetail` is the VISIBLE
|
|
934
1308
|
// heading the overlay falls back to when the host passes no title;
|
|
935
1309
|
// `openAsFullPage` is the icon-only expand button's default accessible
|
|
@@ -969,7 +1343,6 @@ const en = {
|
|
|
969
1343
|
viewAll: 'View All',
|
|
970
1344
|
new: 'New',
|
|
971
1345
|
add: 'Add',
|
|
972
|
-
emptyValue: '—',
|
|
973
1346
|
activity: 'Activity',
|
|
974
1347
|
history: 'History',
|
|
975
1348
|
historyEmpty: 'No history yet',
|
|
@@ -984,6 +1357,7 @@ const en = {
|
|
|
984
1357
|
sortBy: 'Sort by',
|
|
985
1358
|
filterPlaceholder: 'Filter…',
|
|
986
1359
|
highlightFields: 'Key Fields',
|
|
1360
|
+
highlightsLabel: 'Record highlights',
|
|
987
1361
|
// Comments
|
|
988
1362
|
comments: 'Comments',
|
|
989
1363
|
searchComments: 'Search comments…',
|
|
@@ -995,8 +1369,14 @@ const en = {
|
|
|
995
1369
|
unpin: 'Unpin',
|
|
996
1370
|
justNow: 'just now',
|
|
997
1371
|
minutesAgo: '{{count}}m ago',
|
|
1372
|
+
minutesAgo_one: '{{count}}m ago',
|
|
1373
|
+
minutesAgo_other: '{{count}}m ago',
|
|
998
1374
|
hoursAgo: '{{count}}h ago',
|
|
1375
|
+
hoursAgo_one: '{{count}}h ago',
|
|
1376
|
+
hoursAgo_other: '{{count}}h ago',
|
|
999
1377
|
daysAgo: '{{count}}d ago',
|
|
1378
|
+
daysAgo_one: '{{count}}d ago',
|
|
1379
|
+
daysAgo_other: '{{count}}d ago',
|
|
1000
1380
|
// Activity feed actors
|
|
1001
1381
|
systemActor: 'System',
|
|
1002
1382
|
unknownUser: 'Unknown',
|
|
@@ -1010,7 +1390,8 @@ const en = {
|
|
|
1010
1390
|
// Attachments
|
|
1011
1391
|
dropFilesToUpload: 'Drop files here or click to upload',
|
|
1012
1392
|
attachmentCount: '{{count}} attachment',
|
|
1013
|
-
|
|
1393
|
+
attachmentCount_one: '{{count}} attachment',
|
|
1394
|
+
attachmentCount_other: '{{count}} attachments',
|
|
1014
1395
|
removeAttachment: 'Remove attachment',
|
|
1015
1396
|
// Record Attachments panel (enable.files, objectstack#4358)
|
|
1016
1397
|
attachments: 'Attachments',
|
|
@@ -1024,12 +1405,10 @@ const en = {
|
|
|
1024
1405
|
attachmentDownloadDenied: "You don't have access to download this attachment.",
|
|
1025
1406
|
attachmentAuthRequired: 'Please sign in to download this attachment.',
|
|
1026
1407
|
attachmentPermissionDenied: "You don't have permission to do that.",
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
previousVersion: 'Previous',
|
|
1032
|
-
currentVersion: 'Current',
|
|
1408
|
+
attachmentsAccessDenied: "You don't have access to these attachments.",
|
|
1409
|
+
attachmentsLoadFailed: "We couldn't load the attachments for this record.",
|
|
1410
|
+
attachmentsApiUnavailable: 'The attachments list is not available on this object.',
|
|
1411
|
+
retryLoadAttachments: 'Retry',
|
|
1033
1412
|
// Discussion
|
|
1034
1413
|
discussion: 'Discussion',
|
|
1035
1414
|
showDiscussion: 'Show Discussion ({{count}})',
|
|
@@ -1047,23 +1426,16 @@ const en = {
|
|
|
1047
1426
|
// Subscription
|
|
1048
1427
|
subscribedTooltip: 'Subscribed — click to unsubscribe',
|
|
1049
1428
|
unsubscribedTooltip: 'Subscribe to notifications',
|
|
1050
|
-
//
|
|
1051
|
-
firstRecord: 'First record (Home)',
|
|
1052
|
-
previousRecordKey: 'Previous record (←)',
|
|
1053
|
-
nextRecordKey: 'Next record (→)',
|
|
1054
|
-
lastRecord: 'Last record (End)',
|
|
1429
|
+
// The reference rail's empty related-record list
|
|
1055
1430
|
noRecords: 'No records',
|
|
1056
|
-
// objectui#3863 — the BASE key
|
|
1057
|
-
//
|
|
1058
|
-
//
|
|
1059
|
-
//
|
|
1060
|
-
//
|
|
1061
|
-
// `record-reference-rail.tsx`, which `check:i18n-keys` now judges as class 3.
|
|
1431
|
+
// objectui#3863 — the BASE key; since objectui#11432 every pack also spells out
|
|
1432
|
+
// each CLDR category its language selects, so with a count no pack reaches the
|
|
1433
|
+
// base. In `en` this value is parity ballast — and it must stay byte-identical to
|
|
1434
|
+
// the call site's inline `defaultValue` in `record-reference-rail.tsx`, which
|
|
1435
|
+
// `check:i18n-keys` now judges as class 3.
|
|
1062
1436
|
showEmptyRelated: '+ {{count}} empty',
|
|
1063
1437
|
showEmptyRelated_one: '+ {{count}} empty',
|
|
1064
1438
|
showEmptyRelated_other: '+ {{count}} empty',
|
|
1065
|
-
searchWhileNavigating: 'Search while navigating',
|
|
1066
|
-
searchRecords: 'Search records…',
|
|
1067
1439
|
// Activity timeline
|
|
1068
1440
|
allActivity: 'All Activity',
|
|
1069
1441
|
commentsOnly: 'Comments Only',
|
|
@@ -1071,13 +1443,29 @@ const en = {
|
|
|
1071
1443
|
tasksOnly: 'Tasks Only',
|
|
1072
1444
|
leaveCommentPlaceholder: 'Leave a comment… (Ctrl+Enter to submit)',
|
|
1073
1445
|
noActivity: 'No activity recorded',
|
|
1446
|
+
activityAccessDenied: "You don't have permission to view activity on this record.",
|
|
1447
|
+
commentsAccessDenied: "You don't have permission to view comments on this record.",
|
|
1448
|
+
// objectui#7149 — the rest of `ActivityTimeline`. The four chip labels the
|
|
1449
|
+
// `detail.*` pack did not already name, and the `formatFieldChange`
|
|
1450
|
+
// sentences, which are assembled in code and so need interpolation holes.
|
|
1451
|
+
allFilter: 'All',
|
|
1452
|
+
createsFilter: 'Creates',
|
|
1453
|
+
deletesFilter: 'Deletes',
|
|
1454
|
+
statusChangesFilter: 'Status Changes',
|
|
1455
|
+
activityEmptyValue: '(empty)',
|
|
1456
|
+
activityFieldChanged: 'Changed {{field}} from "{{old}}" to "{{new}}"',
|
|
1457
|
+
activityCreated: 'Created this record',
|
|
1458
|
+
activityDeleted: 'Deleted this record',
|
|
1459
|
+
activityStatusChanged: 'Changed status to "{{value}}"',
|
|
1460
|
+
activityUpdated: 'Updated record',
|
|
1074
1461
|
loadMore: 'Load more',
|
|
1075
1462
|
edited: '(edited)',
|
|
1076
1463
|
via: 'via {{source}}',
|
|
1077
1464
|
viewSource: 'View source',
|
|
1078
1465
|
// Replies
|
|
1079
1466
|
replyCount: '{{count}} reply',
|
|
1080
|
-
|
|
1467
|
+
replyCount_one: '{{count}} reply',
|
|
1468
|
+
replyCount_other: '{{count}} replies',
|
|
1081
1469
|
replyPlaceholder: 'Reply…',
|
|
1082
1470
|
// Aria labels
|
|
1083
1471
|
filterActivity: 'Filter activity',
|
|
@@ -1090,13 +1478,54 @@ const en = {
|
|
|
1090
1478
|
copyPhone: 'Copy phone number',
|
|
1091
1479
|
copyRecordId: 'Copy record ID',
|
|
1092
1480
|
showEmptyFields: 'Show {{count}} empty fields',
|
|
1481
|
+
showEmptyFields_one: 'Show {{count}} empty field',
|
|
1482
|
+
showEmptyFields_other: 'Show {{count}} empty fields',
|
|
1093
1483
|
hideEmptyFields: 'Hide empty fields',
|
|
1094
1484
|
noValue: 'No value',
|
|
1485
|
+
unresolvedReference: 'Unresolved reference: {{value}} was not resolved to a user',
|
|
1486
|
+
unresolvedLookupReference: 'Unresolved reference: {{value}} was not resolved to a record on this screen',
|
|
1487
|
+
// Cell-level COUNT phrases for the `repeater` and file cells
|
|
1488
|
+
// (objectui#8441). Both were written straight into the renderer before this
|
|
1489
|
+
// — `repeater` as a number plus a hardcoded Chinese unit word, which every
|
|
1490
|
+
// reader on every locale saw, and `FileCellRenderer` as an English-only
|
|
1491
|
+
// `count === 1 ? 'file' : 'files'`, which is not plural-safe anywhere else.
|
|
1492
|
+
// One channel, two call sites.
|
|
1493
|
+
//
|
|
1494
|
+
// REAL i18next plural families — the one count shape this repo uses since
|
|
1495
|
+
// objectui#11445 retired the code-selected `xxxCountOne` / `xxxCountPlural`
|
|
1496
|
+
// sibling keys. i18next asks `Intl.PluralRules` for the
|
|
1497
|
+
// ONE suffix a number needs, so each pack carries every category its language
|
|
1498
|
+
// selects (`ru` `_few`/`_many`, `ar` `_zero`/`_two`/`_few`/`_many` —
|
|
1499
|
+
// objectui#11432) plus the base key (objectui#3863).
|
|
1500
|
+
// `all-locales-key-parity.test.ts` owns both rules.
|
|
1501
|
+
repeaterItemCount: '{{count}} items',
|
|
1502
|
+
repeaterItemCount_one: '{{count}} item',
|
|
1503
|
+
repeaterItemCount_other: '{{count}} items',
|
|
1504
|
+
fileCount: '{{count}} files',
|
|
1505
|
+
fileCount_one: '{{count}} file',
|
|
1506
|
+
fileCount_other: '{{count}} files',
|
|
1095
1507
|
},
|
|
1096
1508
|
chart: {
|
|
1097
|
-
noData: 'No chart data available',
|
|
1098
1509
|
loading: 'Loading chart…',
|
|
1510
|
+
refreshing: 'Refreshing…',
|
|
1099
1511
|
nullCategory: '(None)',
|
|
1512
|
+
// The refusal a scatter renders when handed more than one series
|
|
1513
|
+
// (objectui#7194): it binds ONE measure, so a second series was painted at
|
|
1514
|
+
// the first one's y values. One short sentence on purpose — this pack is
|
|
1515
|
+
// eagerly loaded and the `framework` chunk's gzip ceiling has ~0.2 KB of
|
|
1516
|
+
// headroom; the series keys are rendered by the chart as data, after it.
|
|
1517
|
+
scatterOneMeasure: 'A scatter plots one measure. Keep exactly one series:',
|
|
1518
|
+
// The refusal an object-bound chart renders when it declares no category
|
|
1519
|
+
// axis (objectui#8168) — `aggregate.groupBy` / `xAxisKey` / `xAxis.field`
|
|
1520
|
+
// all absent, so `runAggregate` would have grouped on a name nobody wrote.
|
|
1521
|
+
// The twin of `timeline.unconfigured.noDateAxis`. ONE short sentence, for
|
|
1522
|
+
// the same reason `scatterOneMeasure` above is one: the packs ship it ten
|
|
1523
|
+
// times, and the binding names are rendered by the component after it
|
|
1524
|
+
// rather than interpolated, so a rung added to or retired from the
|
|
1525
|
+
// resolver cannot leave this sentence naming a stale vocabulary.
|
|
1526
|
+
unconfigured: {
|
|
1527
|
+
noCategoryAxis: 'Chart category axis required — an object-bound chart will not invent one. Declare one of:',
|
|
1528
|
+
},
|
|
1100
1529
|
},
|
|
1101
1530
|
report: {
|
|
1102
1531
|
total: 'Total',
|
|
@@ -1138,93 +1567,140 @@ const en = {
|
|
|
1138
1567
|
panelTitle: 'Edit report',
|
|
1139
1568
|
},
|
|
1140
1569
|
},
|
|
1141
|
-
map: {
|
|
1142
|
-
searchLocations: 'Search locations…',
|
|
1143
|
-
locationDetails: 'Location Details',
|
|
1144
|
-
markersCount: '{{count}} markers',
|
|
1145
|
-
invalidCoordinates: '{{count}} record with missing or invalid coordinates excluded from the map.',
|
|
1146
|
-
invalidCoordinatesPlural: '{{count}} records with missing or invalid coordinates excluded from the map.',
|
|
1147
|
-
},
|
|
1148
|
-
workflow: {
|
|
1149
|
-
draft: 'Draft',
|
|
1150
|
-
active: 'Active',
|
|
1151
|
-
paused: 'Paused',
|
|
1152
|
-
completed: 'Completed',
|
|
1153
|
-
cancelled: 'Cancelled',
|
|
1154
|
-
save: 'Save',
|
|
1155
|
-
publish: 'Publish',
|
|
1156
|
-
addNode: 'Add Node',
|
|
1157
|
-
workflowFlow: 'Workflow Flow',
|
|
1158
|
-
properties: 'Properties',
|
|
1159
|
-
connections: 'Connections',
|
|
1160
|
-
quickConnect: 'Quick Connect',
|
|
1161
|
-
fromPlaceholder: 'From…',
|
|
1162
|
-
toPlaceholder: 'To…',
|
|
1163
|
-
connect: 'Connect',
|
|
1164
|
-
label: 'Label',
|
|
1165
|
-
type: 'Type',
|
|
1166
|
-
description: 'Description',
|
|
1167
|
-
assignee: 'Assignee',
|
|
1168
|
-
assigneeType: 'Assignee Type',
|
|
1169
|
-
user: 'User',
|
|
1170
|
-
role: 'Role',
|
|
1171
|
-
group: 'Group',
|
|
1172
|
-
expression: 'Expression',
|
|
1173
|
-
timeoutMinutes: 'Timeout (minutes)',
|
|
1174
|
-
selectNodeToEdit: 'Select a node to edit its properties',
|
|
1175
|
-
workflowTitle: 'Workflow Title',
|
|
1176
|
-
newWorkflow: 'New Workflow',
|
|
1177
|
-
outConnections: '{{count}} out',
|
|
1178
|
-
start: 'Start',
|
|
1179
|
-
end: 'End',
|
|
1180
|
-
task: 'Task',
|
|
1181
|
-
userTask: 'User Task',
|
|
1182
|
-
serviceTask: 'Service Task',
|
|
1183
|
-
scriptTask: 'Script Task',
|
|
1184
|
-
approval: 'Approval',
|
|
1185
|
-
condition: 'Condition',
|
|
1186
|
-
parallelGateway: 'Parallel Gateway',
|
|
1187
|
-
joinGateway: 'Join Gateway',
|
|
1188
|
-
boundaryEvent: 'Boundary Event',
|
|
1189
|
-
delay: 'Delay',
|
|
1190
|
-
notification: 'Notification',
|
|
1191
|
-
webhook: 'Webhook',
|
|
1192
|
-
allowConcurrency: 'Allow (run concurrently)',
|
|
1193
|
-
forbidConcurrency: 'Forbid (skip new)',
|
|
1194
|
-
replaceConcurrency: 'Replace (cancel existing)',
|
|
1195
|
-
queueConcurrency: 'Queue (run after current)',
|
|
1196
|
-
conditionEvent: 'Condition',
|
|
1197
|
-
manualEvent: 'Manual',
|
|
1198
|
-
webhookEvent: 'Webhook',
|
|
1199
|
-
timerEvent: 'Timer',
|
|
1200
|
-
signalEvent: 'Signal',
|
|
1201
|
-
versionHistory: 'Version History',
|
|
1202
|
-
importBpmn: 'Import BPMN',
|
|
1203
|
-
exportBpmn: 'Export BPMN',
|
|
1204
|
-
undo: 'Undo',
|
|
1205
|
-
redo: 'Redo',
|
|
1206
|
-
resetZoom: 'Reset zoom',
|
|
1207
|
-
},
|
|
1208
1570
|
designer: {
|
|
1209
1571
|
undo: 'Undo',
|
|
1210
1572
|
redo: 'Redo',
|
|
1211
1573
|
},
|
|
1212
1574
|
dashboard: {
|
|
1213
1575
|
addWidget: 'Add widget',
|
|
1214
|
-
removeWidget: 'Remove widget',
|
|
1215
1576
|
editLayout: 'Edit layout',
|
|
1216
1577
|
saveLayout: 'Save layout',
|
|
1217
1578
|
resetLayout: 'Reset layout',
|
|
1218
1579
|
total: 'Total',
|
|
1219
|
-
noDataAvailable: 'No data available',
|
|
1220
1580
|
noDataSourceFor: 'No data source available for',
|
|
1221
|
-
|
|
1581
|
+
// objectui#7063 — the DEFAULT empty state every dashboard widget renders
|
|
1582
|
+
// when its query SUCCEEDED and returned nothing. It replaced the terse
|
|
1583
|
+
// per-widget `noRows` / `noDataAvailable` fragments at the render site;
|
|
1584
|
+
// objectui#7125 deleted those two keys from all ten packs once nothing
|
|
1585
|
+
// read them. The copy here has to read as a state rather than a failure,
|
|
1586
|
+
// which is why it says the widget loaded. `sourceLabel` carries its own
|
|
1587
|
+
// punctuation so the call site concatenates no separator (see
|
|
1588
|
+
// `WidgetEmptyState`).
|
|
1589
|
+
empty: {
|
|
1590
|
+
title: 'No data yet',
|
|
1591
|
+
message: 'This widget loaded successfully and its query returned no records yet.',
|
|
1592
|
+
sourceLabel: 'Source:',
|
|
1593
|
+
},
|
|
1222
1594
|
loading: 'Loading…',
|
|
1595
|
+
refreshing: 'Refreshing…',
|
|
1596
|
+
refreshAll: 'Refresh All',
|
|
1597
|
+
refreshDashboard: 'Refresh dashboard',
|
|
1223
1598
|
pickMeasures: 'Pick measures (values) for this dataset widget.',
|
|
1224
1599
|
datasetUnsupported: 'This data source does not support dataset queries.',
|
|
1600
|
+
widgetForbiddenTitle: 'You don’t have access',
|
|
1601
|
+
widgetForbiddenMessage: 'You don’t have permission to view the data behind this widget.',
|
|
1225
1602
|
details: 'Details',
|
|
1226
1603
|
exportCsv: 'Export CSV',
|
|
1227
1604
|
openInList: 'Open in list',
|
|
1605
|
+
config: {
|
|
1606
|
+
breadcrumb: {
|
|
1607
|
+
dashboard: 'Dashboard',
|
|
1608
|
+
configuration: 'Configuration',
|
|
1609
|
+
widget: 'Widget',
|
|
1610
|
+
chart: 'Chart',
|
|
1611
|
+
table: 'Table',
|
|
1612
|
+
pivotTable: 'Pivot table',
|
|
1613
|
+
},
|
|
1614
|
+
section: {
|
|
1615
|
+
general: 'General',
|
|
1616
|
+
layout: 'Layout',
|
|
1617
|
+
data: 'Data',
|
|
1618
|
+
dataBinding: 'Data Binding',
|
|
1619
|
+
appearance: 'Appearance',
|
|
1620
|
+
},
|
|
1621
|
+
field: {
|
|
1622
|
+
title: 'Title',
|
|
1623
|
+
description: 'Description',
|
|
1624
|
+
columns: 'Columns',
|
|
1625
|
+
gap: 'Gap',
|
|
1626
|
+
rowHeight: 'Row height (px)',
|
|
1627
|
+
autoRefresh: 'Auto refresh',
|
|
1628
|
+
showDescription: 'Show description',
|
|
1629
|
+
theme: 'Theme',
|
|
1630
|
+
widgetType: 'Widget type',
|
|
1631
|
+
colorVariant: 'Color variant',
|
|
1632
|
+
dataset: 'Dataset',
|
|
1633
|
+
dimensions: 'Dimensions',
|
|
1634
|
+
values: 'Values',
|
|
1635
|
+
width: 'Width (columns)',
|
|
1636
|
+
height: 'Height (rows)',
|
|
1637
|
+
},
|
|
1638
|
+
placeholder: {
|
|
1639
|
+
dashboardTitle: 'Dashboard title',
|
|
1640
|
+
dashboardDescription: 'Short summary shown under the title',
|
|
1641
|
+
widgetTitle: 'Widget title',
|
|
1642
|
+
widgetDescription: 'Widget description',
|
|
1643
|
+
datasetName: 'Dataset name',
|
|
1644
|
+
selectDataset: 'Select dataset…',
|
|
1645
|
+
searchDatasets: 'Search datasets…',
|
|
1646
|
+
addDimension: 'Add dimension…',
|
|
1647
|
+
addMeasure: 'Add measure…',
|
|
1648
|
+
searchMembers: 'Search…',
|
|
1649
|
+
},
|
|
1650
|
+
empty: {
|
|
1651
|
+
datasets: 'No datasets found.',
|
|
1652
|
+
dimensions: 'No dimensions selected.',
|
|
1653
|
+
measures: 'No measures selected.',
|
|
1654
|
+
nothingToAdd: 'Nothing left to add.',
|
|
1655
|
+
},
|
|
1656
|
+
help: {
|
|
1657
|
+
dataset: 'The semantic-layer dataset this widget binds to (ADR-0021).',
|
|
1658
|
+
dimensions: 'Group/split the values by these dataset dimensions.',
|
|
1659
|
+
dimensionsPivot: 'Group/split fields. The last dimension spreads across as columns.',
|
|
1660
|
+
values: 'Measure(s) from the dataset to display (at least one).',
|
|
1661
|
+
},
|
|
1662
|
+
action: {
|
|
1663
|
+
add: 'Add',
|
|
1664
|
+
remove: 'Remove {{name}}',
|
|
1665
|
+
},
|
|
1666
|
+
refresh: {
|
|
1667
|
+
off: 'Off',
|
|
1668
|
+
every30s: 'Every 30s',
|
|
1669
|
+
every1m: 'Every 1 min',
|
|
1670
|
+
every5m: 'Every 5 min',
|
|
1671
|
+
every15m: 'Every 15 min',
|
|
1672
|
+
every30m: 'Every 30 min',
|
|
1673
|
+
every1h: 'Every 1 hour',
|
|
1674
|
+
},
|
|
1675
|
+
themeOption: {
|
|
1676
|
+
light: 'Light',
|
|
1677
|
+
dark: 'Dark',
|
|
1678
|
+
auto: 'Auto',
|
|
1679
|
+
},
|
|
1680
|
+
widgetType: {
|
|
1681
|
+
metric: 'Metric',
|
|
1682
|
+
bar: 'Bar Chart',
|
|
1683
|
+
horizontalBar: 'Horizontal Bar',
|
|
1684
|
+
line: 'Line Chart',
|
|
1685
|
+
pie: 'Pie Chart',
|
|
1686
|
+
donut: 'Donut Chart',
|
|
1687
|
+
area: 'Area Chart',
|
|
1688
|
+
scatter: 'Scatter Plot',
|
|
1689
|
+
funnel: 'Funnel',
|
|
1690
|
+
table: 'Table',
|
|
1691
|
+
pivot: 'Pivot Table',
|
|
1692
|
+
},
|
|
1693
|
+
color: {
|
|
1694
|
+
default: 'Default',
|
|
1695
|
+
blue: 'Blue',
|
|
1696
|
+
teal: 'Teal',
|
|
1697
|
+
orange: 'Orange',
|
|
1698
|
+
purple: 'Purple',
|
|
1699
|
+
success: 'Success',
|
|
1700
|
+
warning: 'Warning',
|
|
1701
|
+
danger: 'Danger',
|
|
1702
|
+
},
|
|
1703
|
+
},
|
|
1228
1704
|
trend: {
|
|
1229
1705
|
vsLastQuarter: 'vs last quarter',
|
|
1230
1706
|
vsLastMonth: 'vs last month',
|
|
@@ -1257,24 +1733,6 @@ const en = {
|
|
|
1257
1733
|
},
|
|
1258
1734
|
},
|
|
1259
1735
|
},
|
|
1260
|
-
configPanel: {
|
|
1261
|
-
save: 'Save',
|
|
1262
|
-
discard: 'Discard',
|
|
1263
|
-
close: 'Close',
|
|
1264
|
-
layout: 'Layout',
|
|
1265
|
-
columns: 'Columns',
|
|
1266
|
-
gap: 'Gap',
|
|
1267
|
-
rowHeight: 'Row height',
|
|
1268
|
-
data: 'Data',
|
|
1269
|
-
refreshInterval: 'Refresh interval',
|
|
1270
|
-
appearance: 'Appearance',
|
|
1271
|
-
title: 'Title',
|
|
1272
|
-
showDescription: 'Show description',
|
|
1273
|
-
theme: 'Theme',
|
|
1274
|
-
configuration: 'Configuration',
|
|
1275
|
-
general: 'General',
|
|
1276
|
-
advanced: 'Advanced',
|
|
1277
|
-
},
|
|
1278
1736
|
appDesigner: {
|
|
1279
1737
|
createApp: 'Create Application',
|
|
1280
1738
|
editApp: 'Edit Application',
|
|
@@ -1287,10 +1745,6 @@ const en = {
|
|
|
1287
1745
|
appDescription: 'Description',
|
|
1288
1746
|
appIcon: 'Icon',
|
|
1289
1747
|
template: 'Template',
|
|
1290
|
-
layout: 'Layout',
|
|
1291
|
-
layoutSidebar: 'Sidebar',
|
|
1292
|
-
layoutHeader: 'Header',
|
|
1293
|
-
layoutEmpty: 'Empty',
|
|
1294
1748
|
selectObjects: 'Select Objects',
|
|
1295
1749
|
searchObjects: 'Search objects…',
|
|
1296
1750
|
selectAll: 'Select All',
|
|
@@ -1299,7 +1753,6 @@ const en = {
|
|
|
1299
1753
|
addGroup: 'Add Group',
|
|
1300
1754
|
addUrl: 'Add URL',
|
|
1301
1755
|
addSeparator: 'Add Separator',
|
|
1302
|
-
noNavItems: 'No navigation items yet.',
|
|
1303
1756
|
logoUrl: 'Logo URL',
|
|
1304
1757
|
primaryColor: 'Primary Color',
|
|
1305
1758
|
faviconUrl: 'Favicon URL',
|
|
@@ -1325,16 +1778,13 @@ const en = {
|
|
|
1325
1778
|
showSort: 'Show Sort',
|
|
1326
1779
|
appearance: 'Appearance',
|
|
1327
1780
|
rowHeight: 'Row Height',
|
|
1328
|
-
stripedRows: 'Striped Rows',
|
|
1329
|
-
bordered: 'Bordered',
|
|
1330
1781
|
livePreview: 'Live Preview',
|
|
1331
|
-
stepBasicDesc: 'Name, title, and
|
|
1782
|
+
stepBasicDesc: 'Name, title, and icon',
|
|
1332
1783
|
stepObjectsDesc: 'Select business objects',
|
|
1333
1784
|
stepNavigationDesc: 'Build navigation tree',
|
|
1334
1785
|
stepBrandingDesc: 'Logo, colors, and favicon',
|
|
1335
1786
|
noObjectsFound: 'No objects found.',
|
|
1336
1787
|
noNavItemsHint: 'No navigation items yet. Select objects in the previous step or add items manually.',
|
|
1337
|
-
separator: 'Separator',
|
|
1338
1788
|
separatorLabel: '— Separator —',
|
|
1339
1789
|
newGroup: 'New Group',
|
|
1340
1790
|
newLink: 'New Link',
|
|
@@ -1368,6 +1818,7 @@ const en = {
|
|
|
1368
1818
|
navTypeSeparator: 'Separator',
|
|
1369
1819
|
navTypeAction: 'Action',
|
|
1370
1820
|
navTypeComponent: 'Component',
|
|
1821
|
+
navTypeDoc: 'Doc',
|
|
1371
1822
|
navEditIcon: 'Edit icon',
|
|
1372
1823
|
navToggleVisible: 'Toggle visibility',
|
|
1373
1824
|
navHidden: 'Hidden',
|
|
@@ -1440,17 +1891,13 @@ const en = {
|
|
|
1440
1891
|
unique: 'Unique',
|
|
1441
1892
|
readOnly: 'Read Only',
|
|
1442
1893
|
hidden: 'Hidden',
|
|
1443
|
-
indexed: 'Indexed',
|
|
1444
1894
|
externalId: 'External ID',
|
|
1445
1895
|
trackHistory: 'Track History',
|
|
1446
1896
|
defaultValue: 'Default Value',
|
|
1447
1897
|
placeholder: 'Placeholder',
|
|
1448
1898
|
referenceTo: 'Reference To',
|
|
1449
|
-
formula: 'Formula',
|
|
1450
1899
|
options: 'Options',
|
|
1451
1900
|
addOption: 'Add Option',
|
|
1452
|
-
validationRules: 'Validation Rules',
|
|
1453
|
-
addRule: 'Add Rule',
|
|
1454
1901
|
systemBadge: 'System',
|
|
1455
1902
|
ungrouped: 'General',
|
|
1456
1903
|
deleteConfirmTitle: 'Delete Field?',
|
|
@@ -1469,7 +1916,24 @@ const en = {
|
|
|
1469
1916
|
},
|
|
1470
1917
|
},
|
|
1471
1918
|
console: {
|
|
1919
|
+
// The Studio front door's wordmark (objectui#10043). Its sibling one
|
|
1920
|
+
// route away -- `StudioDesignSurface`'s header Home button -- walks back
|
|
1921
|
+
// to the same place, so both read as the same affordance.
|
|
1922
|
+
studio: {
|
|
1923
|
+
backToHome: 'Back to home',
|
|
1924
|
+
},
|
|
1472
1925
|
saveAdvisoryTitle: 'Saved — the authoring check raised {{count}} advisory finding(s)',
|
|
1926
|
+
saveAdvisoryTitle_one: 'Saved — the authoring check raised {{count}} advisory finding',
|
|
1927
|
+
saveAdvisoryTitle_other: 'Saved — the authoring check raised {{count}} advisory findings',
|
|
1928
|
+
publishAdvisoryTitle: 'Published — the authoring check raised {{count}} advisory finding(s)',
|
|
1929
|
+
publishAdvisoryTitle_one: 'Published — the authoring check raised {{count}} advisory finding',
|
|
1930
|
+
publishAdvisoryTitle_other: 'Published — the authoring check raised {{count}} advisory findings',
|
|
1931
|
+
importMappingsUnavailable: 'Saved import mappings for {{object}} could not be loaded',
|
|
1932
|
+
importMappingsRefused: 'The server refused this request, so this list is empty because it could not be read — not because nothing is registered. Sign in again, or ask an administrator for access.',
|
|
1933
|
+
importMappingsUnreadable: 'This list is empty because it could not be read, not because nothing is registered. Try again, and report this if it keeps happening.',
|
|
1934
|
+
savedViewsUnavailable: 'Saved views for {{object}} could not be loaded',
|
|
1935
|
+
savedViewsRefused: 'The server refused this request, so this list is empty because it could not be read — not because this object has no saved views. Sign in again, or ask an administrator for access.',
|
|
1936
|
+
savedViewsUnreadable: 'This list is empty because it could not be read, not because this object has no saved views. Try again, and report this if it keeps happening.',
|
|
1473
1937
|
title: 'ObjectOS',
|
|
1474
1938
|
initializing: 'Initializing application…',
|
|
1475
1939
|
search: 'Search…',
|
|
@@ -1478,12 +1942,24 @@ const en = {
|
|
|
1478
1942
|
pages: 'Pages',
|
|
1479
1943
|
reports: 'Reports',
|
|
1480
1944
|
system: 'System',
|
|
1945
|
+
// The Setup system page segment after `System` (objectui#10900).
|
|
1946
|
+
marketplace: 'Marketplace',
|
|
1947
|
+
// The console app's own `system/*` pages after `System` (objectui#10969).
|
|
1948
|
+
settings: 'Settings',
|
|
1949
|
+
apps: 'Apps',
|
|
1950
|
+
profile: 'Profile',
|
|
1951
|
+
approvals: 'Approvals',
|
|
1952
|
+
aiApprovals: 'AI Approvals',
|
|
1953
|
+
auditLog: 'Audit Log',
|
|
1481
1954
|
},
|
|
1482
1955
|
nav: {
|
|
1483
1956
|
pinItem: 'Pin {{name}}',
|
|
1484
1957
|
unpinItem: 'Unpin {{name}}',
|
|
1485
1958
|
dragToReorder: 'Drag to reorder',
|
|
1486
1959
|
favorites: 'Favorites',
|
|
1960
|
+
launcherLabel: 'App launcher',
|
|
1961
|
+
menuLabel: 'App navigation',
|
|
1962
|
+
menuEmpty: 'This app has no navigation entries you can open.',
|
|
1487
1963
|
},
|
|
1488
1964
|
settingsHub: {
|
|
1489
1965
|
title: 'Settings',
|
|
@@ -1531,15 +2007,12 @@ const en = {
|
|
|
1531
2007
|
discard: 'Discard',
|
|
1532
2008
|
saveChanges: 'Save changes',
|
|
1533
2009
|
// Save-bar counter. A REAL i18next plural family, not an English-only
|
|
1534
|
-
// `change(s)
|
|
1535
|
-
// elsewhere in this file.
|
|
2010
|
+
// `change(s)`.
|
|
1536
2011
|
//
|
|
1537
|
-
//
|
|
1538
|
-
//
|
|
1539
|
-
//
|
|
1540
|
-
// `
|
|
1541
|
-
// without this base key `ru` would render ENGLISH at counts 2-20.
|
|
1542
|
-
// `all-locales-key-parity.test.ts` owns that rule.
|
|
2012
|
+
// i18next asks `Intl.PluralRules` for the one suffix a language needs, so
|
|
2013
|
+
// each pack spells out every category its language selects — `ru` has
|
|
2014
|
+
// four, `ar` six (objectui#11432) — and keeps the base key
|
|
2015
|
+
// (objectui#3863). `all-locales-key-parity.test.ts` owns both rules.
|
|
1543
2016
|
unsavedCount: '{{count}} unsaved changes',
|
|
1544
2017
|
unsavedCount_one: '{{count}} unsaved change',
|
|
1545
2018
|
unsavedCount_other: '{{count}} unsaved changes',
|
|
@@ -1624,6 +2097,13 @@ const en = {
|
|
|
1624
2097
|
createApp: 'Create New App',
|
|
1625
2098
|
},
|
|
1626
2099
|
ai: {
|
|
2100
|
+
pendingDrafts: {
|
|
2101
|
+
count: '{{count}} change(s) are not published yet — users cannot see them.',
|
|
2102
|
+
publish: 'Publish',
|
|
2103
|
+
published: 'All pending changes are live.',
|
|
2104
|
+
failed: 'Publish failed.',
|
|
2105
|
+
publishedWithFindings: 'Published, but the runtime probes reported problems: {{detail}}',
|
|
2106
|
+
},
|
|
1627
2107
|
usage: {
|
|
1628
2108
|
title: 'AI usage',
|
|
1629
2109
|
meterBuild: 'Build',
|
|
@@ -1633,9 +2113,24 @@ const en = {
|
|
|
1633
2113
|
statusFull: 'Limit reached',
|
|
1634
2114
|
resetsDaily: 'Resets tonight',
|
|
1635
2115
|
resetsMonthly: 'Resets next cycle',
|
|
2116
|
+
// `resetKind: 'weekly'` (free plan's rolling 7-day window, cloud PR
|
|
2117
|
+
// #1852): "N days" (or "N hours" inside the final day). A REAL
|
|
2118
|
+
// i18next plural family — see the `unsavedCount` note above — so the
|
|
2119
|
+
// BASE key carries no suffix and must stay in every pack's lookup
|
|
2120
|
+
// chain (`all-locales-key-parity.test.ts`'s base-key rule).
|
|
2121
|
+
resetsWeeklyDays: 'Resets in {{count}} days',
|
|
2122
|
+
resetsWeeklyDays_one: 'Resets in {{count}} day',
|
|
2123
|
+
resetsWeeklyDays_other: 'Resets in {{count}} days',
|
|
2124
|
+
resetsWeeklyHours: 'Resets in {{count}} hours',
|
|
2125
|
+
resetsWeeklyHours_one: 'Resets in {{count}} hour',
|
|
2126
|
+
resetsWeeklyHours_other: 'Resets in {{count}} hours',
|
|
1636
2127
|
ctaUpgrade: 'Upgrade to keep going',
|
|
1637
2128
|
ctaTopUp: 'Add credits to continue',
|
|
1638
2129
|
ariaLabel: 'AI usage: {{status}}',
|
|
2130
|
+
// objectui#8524 — heading over the pool's read-only split (`breakdown`:
|
|
2131
|
+
// app-building vs data Q&A) in the popover. The rows reuse `meterBuild` /
|
|
2132
|
+
// `meterAsk`; each is a share of the ONE pool, never a second budget.
|
|
2133
|
+
breakdownTitle: 'Used so far',
|
|
1639
2134
|
},
|
|
1640
2135
|
workspaceTitle: 'AI Workspace',
|
|
1641
2136
|
workspaceSubtitle: 'Ask, inspect, and resume conversations',
|
|
@@ -1645,6 +2140,38 @@ const en = {
|
|
|
1645
2140
|
share: 'Share',
|
|
1646
2141
|
shareTitle: 'Share this conversation',
|
|
1647
2142
|
shareDisabledTitle: 'Start chatting to enable sharing',
|
|
2143
|
+
// The build conversation's Build Doctor button (its accessible name,
|
|
2144
|
+
// and its tooltip enabled / before the first message) and the drawer
|
|
2145
|
+
// title it opens (objectui#10900).
|
|
2146
|
+
buildDoctor: 'Build Doctor',
|
|
2147
|
+
buildDoctorTitle: 'Build Doctor — what actually landed?',
|
|
2148
|
+
buildDoctorDisabledTitle: 'Send a message first',
|
|
2149
|
+
// The Build Doctor drawer's body (objectui#10969): its description, the
|
|
2150
|
+
// loading and not-found states, the summary line, the verdict, and each
|
|
2151
|
+
// section's title and hint. What the report itself carries (tool, artifact
|
|
2152
|
+
// and status names, timeline text) is data and stays verbatim.
|
|
2153
|
+
buildDoctorDrawer: {
|
|
2154
|
+
description: 'What the agent claimed vs what is actually live. Read-only diagnostic.',
|
|
2155
|
+
reconciling: 'Reconciling…',
|
|
2156
|
+
notAvailable: 'Not available — the conversation was not found or you are not authorized.',
|
|
2157
|
+
untitled: '(untitled)',
|
|
2158
|
+
summary: '{{turns}} turn(s) · {{messages}} msgs · {{tokens}} tok · {{seconds}}s LLM',
|
|
2159
|
+
allLive: 'All {{count}} attempted change(s) are live — nothing evaporated.',
|
|
2160
|
+
discrepancies: "{{count}} discrepancy(ies) — what the chat said doesn't match what's live.",
|
|
2161
|
+
orphanedTitle: 'Proposed but never applied',
|
|
2162
|
+
orphanedHint: 'A confirm card the agent proposed but no later turn applied — the change silently evaporated.',
|
|
2163
|
+
missingTitle: 'Claimed but missing',
|
|
2164
|
+
missingHint: "A tool result said it was applied, but the artifact isn't live in sys_metadata.",
|
|
2165
|
+
toolErrorsTitle: 'Tool errors',
|
|
2166
|
+
toolErrorsHint: 'Tool calls that returned an error during the build.',
|
|
2167
|
+
verifyTitle: 'Build check (verify_build)',
|
|
2168
|
+
yourApp: 'Your app:',
|
|
2169
|
+
noIssues: '0 issues',
|
|
2170
|
+
issueCount: '{{count}} issue(s)',
|
|
2171
|
+
platformNoise: '{{count}} platform sys_* finding(s) hidden',
|
|
2172
|
+
pendingActions: 'Pending actions',
|
|
2173
|
+
timeline: 'Timeline ({{count}})',
|
|
2174
|
+
},
|
|
1648
2175
|
newChat: 'New',
|
|
1649
2176
|
searchChats: 'Search chats…',
|
|
1650
2177
|
noChatsYet: 'No chats yet',
|
|
@@ -1671,10 +2198,33 @@ const en = {
|
|
|
1671
2198
|
emptyDescription: 'Ask anything — the assistant has access to your current app context.',
|
|
1672
2199
|
switchAssistant: 'Switch assistant',
|
|
1673
2200
|
chooseAgent: 'Choose assistant…',
|
|
2201
|
+
// objectui#8329 — the maker's empty-state prose, and the FIRST sentence a
|
|
2202
|
+
// new user reads on the build surface (it sits above the start chips).
|
|
2203
|
+
// Same ADR-0112 v1 boundary the chips answer to (cloud#1984 /
|
|
2204
|
+
// objectui#7709 for the starters, cloud#2022 for the model's own closing
|
|
2205
|
+
// suggestions): these two descriptions are the product PROMISING, so they
|
|
2206
|
+
// may only name what v1 BUILDS — objects, fields, views, pages,
|
|
2207
|
+
// dashboards, sample data, apps and navigation. `build.description` used
|
|
2208
|
+
// to offer "an app or workflow … objects, screens and automations" and
|
|
2209
|
+
// `editApp.description` "… view or automation"; v1 has no flows, actions
|
|
2210
|
+
// or schedules, so a user who took either at its word was refused
|
|
2211
|
+
// outright — the worst possible answer to the first line on the page.
|
|
2212
|
+
//
|
|
2213
|
+
// NOT the same thing as the platform's manual automation surfaces, which
|
|
2214
|
+
// are real and stay as they are: `home.build.subtitle` (that card opens
|
|
2215
|
+
// Studio, which does author flows), `engine.studio.landing.description`,
|
|
2216
|
+
// `dataImport.optRunAutomations`, `packagedAutomation.*` and the
|
|
2217
|
+
// marketplace `automation` category. The boundary is v1 AI AUTHORING, not
|
|
2218
|
+
// the word "automation".
|
|
2219
|
+
//
|
|
2220
|
+
// REVERT both sentences when ADR-0112 v2 re-adds flows and actions — same
|
|
2221
|
+
// line of the version roadmap as the chips. Every pack's wording is
|
|
2222
|
+
// guarded, in its own script, by
|
|
2223
|
+
// `packages/i18n/src/__tests__/makerEmptyState-v1-scope-8329.test.ts`.
|
|
1674
2224
|
empty: {
|
|
1675
2225
|
build: {
|
|
1676
2226
|
title: 'Build with AI',
|
|
1677
|
-
description: 'Describe an app
|
|
2227
|
+
description: 'Describe an app in plain language — I draft the objects, screens and sample data, then you review and publish.',
|
|
1678
2228
|
},
|
|
1679
2229
|
ask: {
|
|
1680
2230
|
title: 'Ask your data',
|
|
@@ -1683,7 +2233,7 @@ const en = {
|
|
|
1683
2233
|
editApp: {
|
|
1684
2234
|
title: 'Editing “{{app}}”',
|
|
1685
2235
|
titleGeneric: 'Edit this app',
|
|
1686
|
-
description: 'What would you like to change? I’ll modify this app in place — add a field, object, view or
|
|
2236
|
+
description: 'What would you like to change? I’ll modify this app in place — add a field, object, view or dashboard, or adjust what’s already there.',
|
|
1687
2237
|
},
|
|
1688
2238
|
},
|
|
1689
2239
|
clearConversation: 'Clear',
|
|
@@ -1729,6 +2279,11 @@ const en = {
|
|
|
1729
2279
|
changesConfirmed: 'Confirmed',
|
|
1730
2280
|
changesConfirm: 'Confirm',
|
|
1731
2281
|
changesConfirmHint: 'Reply to confirm or adjust this change.',
|
|
2282
|
+
changesApplying: 'Applying…',
|
|
2283
|
+
changesApplied: 'Applied',
|
|
2284
|
+
changesDrafted: 'Saved as draft',
|
|
2285
|
+
changesFailed: 'Not applied',
|
|
2286
|
+
discussing: 'Discussing: {{target}}',
|
|
1732
2287
|
// Wording is load-bearing: this is SENT to the agent and must satisfy the
|
|
1733
2288
|
// cloud confirm gate's English clause `apply (this|the) change`
|
|
1734
2289
|
// (service-ai-studio confirm-gate.ts APPROVAL_RE). "apply what you just
|
|
@@ -1762,23 +2317,41 @@ const en = {
|
|
|
1762
2317
|
recentRecords: 'List the 5 most recently created records.',
|
|
1763
2318
|
recordCounts: 'Count records for each object.',
|
|
1764
2319
|
},
|
|
2320
|
+
// cloud#1984 — these five chips are the maker's own recommendations, so
|
|
2321
|
+
// they may only ask for what ADR-0112 v1 BUILDS: objects, fields, views
|
|
2322
|
+
// (grid/kanban/calendar/gallery), pages, dashboards and sample data. No
|
|
2323
|
+
// wording that promises autonomous behaviour (alert / remind / notify /
|
|
2324
|
+
// automate / status workflow) — v1 has no flows, actions or schedules, and
|
|
2325
|
+
// the model silently degrades such a request into a board or a filtered
|
|
2326
|
+
// view, so the chip would promise an alert and deliver a page. REVERT to
|
|
2327
|
+
// the automation wording when ADR-0112 v2 re-adds flows and actions.
|
|
1765
2328
|
metadataAssistant: {
|
|
1766
|
-
buildCrm: 'Build a sales CRM — customers, contacts, and a
|
|
1767
|
-
buildApp: 'Create a project tracker — projects, tasks with owners and due dates,
|
|
1768
|
-
buildFlow: 'Design a support desk — tickets with priority, a status
|
|
1769
|
-
buildInventory: 'Build an inventory app — products, stock levels, suppliers, and
|
|
1770
|
-
buildRecruiting: 'Make an applicant tracker — candidates, open roles, interview
|
|
2329
|
+
buildCrm: 'Build a sales CRM — customers, contacts, and deals with a stage field, plus a dashboard that totals deal value by stage.',
|
|
2330
|
+
buildApp: 'Create a project tracker — projects, tasks with owners and due dates, a board grouped by status, and a calendar of due dates.',
|
|
2331
|
+
buildFlow: 'Design a support desk — tickets with priority and status fields, a board grouped by status, and links to customers.',
|
|
2332
|
+
buildInventory: 'Build an inventory app — products, stock levels, suppliers, and a view that filters the items below their reorder point.',
|
|
2333
|
+
buildRecruiting: 'Make an applicant tracker — candidates, open roles, an interview-stage field, and a board grouped by stage.',
|
|
1771
2334
|
},
|
|
1772
2335
|
generic: {
|
|
1773
2336
|
help: 'What can you help me with?',
|
|
1774
2337
|
availableObjects: 'List the available data objects.',
|
|
1775
2338
|
recentActivity: 'Summarize my recent activity.',
|
|
1776
2339
|
},
|
|
2340
|
+
// objectui#7709 — the edit-mode starters, shown when the maker is bound
|
|
2341
|
+
// to an EXISTING app (`?package=`). Same rule as the five above: they
|
|
2342
|
+
// may only ask for what ADR-0112 v1 BUILDS. The fourth chip used to be
|
|
2343
|
+
// `addAutomation` ("an approval, a status flow, or a notification") and
|
|
2344
|
+
// every capability it named is refused by v1 (cloud#1956 / PR #1970), so
|
|
2345
|
+
// it now asks for sample data — `seed` IS on v1's whitelist, and having
|
|
2346
|
+
// no data is what an existing app most often lacks. REVERT: when
|
|
2347
|
+
// ADR-0112 v2 re-adds flows and actions, THIS chip's automation wording
|
|
2348
|
+
// comes back as `addAutomation`; the retired string is pinned for every
|
|
2349
|
+
// pack in `packages/i18n/src/__tests__/makerEditChips-v1-scope-7709.test.ts`.
|
|
1777
2350
|
editApp: {
|
|
1778
2351
|
addField: 'Add a field to one of the objects.',
|
|
1779
2352
|
addObject: 'Add a new object and relate it to an existing one.',
|
|
1780
2353
|
addDashboard: 'Add a dashboard for the key metrics.',
|
|
1781
|
-
|
|
2354
|
+
addSampleData: 'Fill the existing objects with realistic sample records so I can demo the app.',
|
|
1782
2355
|
},
|
|
1783
2356
|
},
|
|
1784
2357
|
// objectui#3546 slice four — the AI console surfaces: the /ai chat page's app switcher,
|
|
@@ -1833,6 +2406,29 @@ const en = {
|
|
|
1833
2406
|
older: 'Older',
|
|
1834
2407
|
},
|
|
1835
2408
|
},
|
|
2409
|
+
// objectui#9954 — the environment admin's read-rate report (cloud#2333).
|
|
2410
|
+
// Two anomalous cases, two sets of words: an ABSENT `readsPerWrite` means the
|
|
2411
|
+
// environment wrote nothing at all, so the ratio is unbounded — the most
|
|
2412
|
+
// severe reading, and never a missing number. `{{threshold}}` always comes
|
|
2413
|
+
// from the wire; this repo holds no copy of the line. Report only — the copy
|
|
2414
|
+
// states that nothing is limited or blocked, and must keep doing so.
|
|
2415
|
+
readRate: {
|
|
2416
|
+
ratioTitle: 'Unusual read volume in this environment',
|
|
2417
|
+
ratio: 'Reads are running at {{ratio}} rows for every row written. The platform flags anything above {{threshold}}. Nothing is limited or blocked; this is a report so the read pattern can be reviewed.',
|
|
2418
|
+
noWritesTitle: 'Reads with no writes at all in this environment',
|
|
2419
|
+
noWrites: 'Rows are being read while none at all are being written, so the read rate has no upper bound. This is the most severe reading. The platform flags anything above {{threshold}}. Nothing is limited or blocked; this is a report so the read pattern can be reviewed.',
|
|
2420
|
+
},
|
|
2421
|
+
// objectui#10439 — the environment admin's storage-capacity banner (cloud#2135).
|
|
2422
|
+
// Raised by the tenant runtime's own verdict on `/api/v1/usage/storage`: `warn`
|
|
2423
|
+
// (80% and up) or `blocked` (uploads and bulk imports refused). `{{used}}` and
|
|
2424
|
+
// `{{limit}}` are that response's `usedMb` / `limitMb`, already formatted.
|
|
2425
|
+
storageUsage: {
|
|
2426
|
+
warningTitle: 'Storage is filling up',
|
|
2427
|
+
warning: '{{used}} MB of {{limit}} MB used. Uploads and imports pause once storage is full.',
|
|
2428
|
+
blockedTitle: 'Storage is full: uploads and imports are paused',
|
|
2429
|
+
blocked: '{{used}} MB of {{limit}} MB used. Existing data is untouched, and reading, exporting and editing single records still work.',
|
|
2430
|
+
upgrade: 'Upgrade to continue',
|
|
2431
|
+
},
|
|
1836
2432
|
errors: {
|
|
1837
2433
|
somethingWentWrong: 'Something went wrong',
|
|
1838
2434
|
unexpectedError: 'An unexpected error occurred while rendering this view.',
|
|
@@ -1890,67 +2486,25 @@ const en = {
|
|
|
1890
2486
|
// (rename / pin / set-as-default / configure), so the copy has to cover
|
|
1891
2487
|
// any change to a built-in view rather than name one operation.
|
|
1892
2488
|
cannotEditMetaView: 'This view is built in and defined in code — it cannot be changed.',
|
|
2489
|
+
viewConfigPermissionDenied: 'View settings apply to everyone who uses this view, so changing them requires the Manage Metadata permission. Ask an administrator to make this change.',
|
|
1893
2490
|
cannotDeleteMetaView: 'This view is built in and defined in code — it cannot be deleted.',
|
|
1894
2491
|
expandToPage: 'Open as full page',
|
|
1895
2492
|
allRecords: 'All Records',
|
|
1896
|
-
exitDesignMode: 'Exit Design Mode',
|
|
1897
|
-
enterDesignMode: 'Enter Design Mode',
|
|
1898
|
-
metadataInspector: 'Metadata Inspector',
|
|
1899
|
-
editView: 'Edit View',
|
|
1900
|
-
addView: 'Add View',
|
|
1901
|
-
designTools: 'Design tools',
|
|
1902
2493
|
new: 'New',
|
|
1903
2494
|
import: 'Import',
|
|
1904
2495
|
importTitle: 'Import from CSV',
|
|
1905
2496
|
importedToast: 'Imported {{count}} row(s).',
|
|
2497
|
+
importedToast_one: 'Imported {{count}} row.',
|
|
2498
|
+
importedToast_other: 'Imported {{count}} rows.',
|
|
1906
2499
|
importedWithSkipped: 'Imported {{ok}} row(s); skipped {{skipped}}.',
|
|
1907
2500
|
configureView: 'Configure View',
|
|
1908
|
-
closePanel: 'Close panel',
|
|
1909
|
-
showAdvancedSettings: 'Show advanced settings',
|
|
1910
|
-
showFewerSettings: 'Show fewer settings',
|
|
1911
|
-
page: 'Page',
|
|
1912
|
-
pageConfigHint: 'Toolbar, navigation & view shell settings',
|
|
1913
|
-
listConfigHint: 'Data rendering, columns & appearance for this list type',
|
|
1914
|
-
general: 'General',
|
|
1915
|
-
generalHint: 'View title, description, and type',
|
|
1916
|
-
toolbar: 'Toolbar',
|
|
1917
|
-
toolbarHint: 'Search, filter, sort, group, and density toggles',
|
|
1918
2501
|
toolbarEnabledCount: '{{count}} of {{total}} enabled',
|
|
1919
|
-
navigationSection: 'Navigation',
|
|
1920
|
-
navigationHint: 'Row click behavior and detail view settings',
|
|
1921
|
-
records: 'Records',
|
|
1922
|
-
recordsHint: 'Selection mode, add record, and inline editing',
|
|
1923
|
-
exportPrint: 'Export & Print',
|
|
1924
|
-
exportPrintHint: 'Export formats, printing, and record count display',
|
|
1925
|
-
showAllFields: 'Show All',
|
|
1926
|
-
hideAllFields: 'Hide All',
|
|
1927
2502
|
searchFields: 'Search fields…',
|
|
1928
2503
|
title: 'Title',
|
|
1929
|
-
description: 'Description',
|
|
1930
|
-
data: 'Data',
|
|
1931
|
-
source: 'Source',
|
|
1932
|
-
columns: 'Columns',
|
|
1933
|
-
filterBy: 'Filter by',
|
|
1934
|
-
sortBy: 'Sort by',
|
|
1935
|
-
appearance: 'Appearance',
|
|
1936
|
-
showDescription: 'Show description',
|
|
1937
2504
|
viewType: 'View type',
|
|
1938
|
-
userFilters: 'User filters',
|
|
1939
|
-
enableSearch: 'Enable search',
|
|
1940
|
-
enableFilter: 'Enable filter',
|
|
1941
|
-
enableSort: 'Enable sort',
|
|
1942
|
-
enableHideFields: 'Enable hide fields',
|
|
1943
|
-
enableGroup: 'Enable group',
|
|
1944
|
-
enableColor: 'Enable color',
|
|
1945
|
-
enableDensity: 'Enable density',
|
|
1946
|
-
userActions: 'User actions',
|
|
1947
|
-
addRecordViaForm: 'Add records through a form',
|
|
1948
|
-
advanced: 'Advanced',
|
|
1949
|
-
allowExport: 'Allow export',
|
|
1950
2505
|
recordCount: '{{count}} records',
|
|
1951
|
-
|
|
1952
|
-
|
|
1953
|
-
columnsConfigured: '{{count}} columns',
|
|
2506
|
+
recordCount_one: '{{count}} record',
|
|
2507
|
+
recordCount_other: '{{count}} records',
|
|
1954
2508
|
save: 'Save',
|
|
1955
2509
|
discard: 'Discard',
|
|
1956
2510
|
createView: 'Create View',
|
|
@@ -1961,6 +2515,8 @@ const en = {
|
|
|
1961
2515
|
deleteViewTitle: 'Delete view',
|
|
1962
2516
|
deleteViewConfirm: 'Are you sure you want to delete the view "{{name}}"? This cannot be undone.',
|
|
1963
2517
|
bulkDeleteConfirm: 'Delete {{count}} selected records? This cannot be undone.',
|
|
2518
|
+
bulkDeleteConfirm_one: 'Delete {{count}} selected record? This cannot be undone.',
|
|
2519
|
+
bulkDeleteConfirm_other: 'Delete {{count}} selected records? This cannot be undone.',
|
|
1964
2520
|
duplicateViewName: 'A view with this name already exists.',
|
|
1965
2521
|
viewTypeGrid: 'Grid',
|
|
1966
2522
|
viewTypeGridDesc: 'A spreadsheet-style table of records.',
|
|
@@ -1987,7 +2543,6 @@ const en = {
|
|
|
1987
2543
|
viewNameHelp: 'Machine key (snake_case). Auto-filled from the title — edit if you like.',
|
|
1988
2544
|
viewNameRequired: 'Enter a key (lowercase letters, numbers, underscore). Not auto-filled for non-Latin titles.',
|
|
1989
2545
|
viewNameInvalid: 'Use lowercase letters, numbers and underscores; start with a letter or underscore.',
|
|
1990
|
-
typeOptions: 'Type Options',
|
|
1991
2546
|
groupByField: 'Group by field',
|
|
1992
2547
|
groupByFieldHelp: 'The kanban groups records into columns by this field\'s values.',
|
|
1993
2548
|
startDateField: 'Start date field',
|
|
@@ -2002,7 +2557,6 @@ const en = {
|
|
|
2002
2557
|
longitudeFieldHelp: 'Field providing the longitude coordinate (geo fields only).',
|
|
2003
2558
|
imageField: 'Image field',
|
|
2004
2559
|
imageFieldHelp: 'The gallery cover comes from this image or attachment field.',
|
|
2005
|
-
dateField: 'Date field',
|
|
2006
2560
|
selectField: 'Select field…',
|
|
2007
2561
|
selectOption: 'Select…',
|
|
2008
2562
|
noEligibleFieldForType: 'No eligible field of this type. Add one to the object first.',
|
|
@@ -2015,86 +2569,18 @@ const en = {
|
|
|
2015
2569
|
chartTypePie: 'Pie chart',
|
|
2016
2570
|
chartTypeArea: 'Area chart',
|
|
2017
2571
|
chartTypeScatter: 'Scatter chart',
|
|
2018
|
-
|
|
2019
|
-
|
|
2020
|
-
|
|
2021
|
-
|
|
2022
|
-
|
|
2023
|
-
|
|
2024
|
-
|
|
2025
|
-
|
|
2026
|
-
fieldsVisible: '{{count}} visible',
|
|
2027
|
-
sortsCount: '{{count}} sorts',
|
|
2028
|
-
filtersCount: '{{count}} filters',
|
|
2572
|
+
dataset: 'Dataset',
|
|
2573
|
+
datasetHelp: 'The chart reads its numbers from this dataset of the object.',
|
|
2574
|
+
chartMeasure: 'Measure',
|
|
2575
|
+
chartMeasureHelp: 'The dataset measure plotted on the value axis.',
|
|
2576
|
+
chartDimension: 'Dimension',
|
|
2577
|
+
chartDimensionHelp: 'The dataset dimension the values are grouped by (optional).',
|
|
2578
|
+
viewTypeUnavailableDataset: 'This object exposes no dataset to chart.',
|
|
2579
|
+
noDatasetMeasure: 'This dataset declares no measure to chart.',
|
|
2029
2580
|
endDateField: 'End date field',
|
|
2030
|
-
color: 'Color',
|
|
2031
|
-
fieldTextColor: 'Field text color',
|
|
2032
|
-
rowHeight: 'Row height',
|
|
2033
|
-
wrapHeaders: 'Wrap headers',
|
|
2034
|
-
showFieldDescriptions: 'Show field descriptions',
|
|
2035
|
-
collapseAllByDefault: 'Collapse all by default',
|
|
2036
|
-
striped: 'Striped rows',
|
|
2037
|
-
bordered: 'Bordered cells',
|
|
2038
|
-
inlineEdit: 'Edit records inline',
|
|
2039
|
-
addDeleteRecordsInline: 'Add/delete records inline',
|
|
2040
|
-
clickIntoRecordDetails: 'Click into record details',
|
|
2041
|
-
navigationMode: 'Navigation mode',
|
|
2042
|
-
navigationWidth: 'Navigation width',
|
|
2043
|
-
navigationWidthHint: 'Available for drawer, modal, and split navigation modes',
|
|
2044
|
-
openNewTab: 'Open in new tab',
|
|
2045
|
-
openNewTabHint: 'Available for page and new window navigation modes',
|
|
2046
|
-
selectionMode: 'Selection mode',
|
|
2047
|
-
selectionNone: 'None',
|
|
2048
|
-
selectionSingle: 'Single',
|
|
2049
|
-
selectionMultiple: 'Multiple',
|
|
2050
|
-
pageSize: 'Page size',
|
|
2051
|
-
pageSizeOptions: 'Page size options',
|
|
2052
|
-
exportFormats: 'Export formats',
|
|
2053
|
-
exportMaxRecords: 'Max records',
|
|
2054
|
-
exportIncludeHeaders: 'Include headers',
|
|
2055
|
-
exportFileNamePrefix: 'File name prefix',
|
|
2056
|
-
searchableFields: 'Searchable fields',
|
|
2057
|
-
filterableFields: 'Filterable fields',
|
|
2058
|
-
resizableColumns: 'Resizable columns',
|
|
2059
|
-
densityCompact: 'Compact',
|
|
2060
|
-
densityComfortable: 'Comfortable',
|
|
2061
|
-
densitySpacious: 'Spacious',
|
|
2062
|
-
densityMode: 'Density mode',
|
|
2063
|
-
hiddenFields: 'Hidden fields',
|
|
2064
|
-
rowActions: 'Row actions',
|
|
2065
|
-
bulkActions: 'Bulk actions',
|
|
2066
|
-
sharing: 'Sharing',
|
|
2067
|
-
sharingEnabled: 'Enable sharing',
|
|
2068
|
-
sharingVisibility: 'Visibility',
|
|
2069
|
-
addRecordEnabled: 'Enable add record',
|
|
2070
|
-
addRecordPosition: 'Position',
|
|
2071
|
-
addRecordMode: 'Mode',
|
|
2072
|
-
addRecordFormView: 'Form view',
|
|
2073
|
-
conditionalFormatting: 'Conditional formatting',
|
|
2074
|
-
addRule: 'Add rule',
|
|
2075
|
-
quickFilters: 'Quick filters',
|
|
2076
|
-
addQuickFilter: 'Add quick filter',
|
|
2077
|
-
ufElements: 'Elements',
|
|
2078
|
-
ufDropdown: 'Dropdown',
|
|
2079
2581
|
ufTabs: 'Tabs',
|
|
2080
|
-
ufToggle: 'Toggle',
|
|
2081
2582
|
ufAddField: '+ Add filter field…',
|
|
2082
|
-
ufNoFields: 'No fields available',
|
|
2083
|
-
ufAddTab: '+ Add tab',
|
|
2084
|
-
ufTabLabel: 'Label',
|
|
2085
2583
|
ufShowAllRecords: 'Show "All records" tab',
|
|
2086
|
-
ufAllowAddTab: 'Allow adding tabs',
|
|
2087
|
-
showRecordCount: 'Show record count',
|
|
2088
|
-
allowPrinting: 'Allow printing',
|
|
2089
|
-
virtualScroll: 'Virtual scroll',
|
|
2090
|
-
emptyStateTitle: 'Empty state title',
|
|
2091
|
-
emptyStateMessage: 'Empty state message',
|
|
2092
|
-
emptyStateIcon: 'Empty state icon',
|
|
2093
|
-
ariaLabel: 'ARIA label',
|
|
2094
|
-
ariaDescribedBy: 'ARIA described by',
|
|
2095
|
-
ariaLive: 'ARIA live',
|
|
2096
|
-
accessibility: 'Accessibility',
|
|
2097
|
-
viewTabs: 'View Tabs',
|
|
2098
2584
|
},
|
|
2099
2585
|
localeSwitcher: {
|
|
2100
2586
|
label: 'Language',
|
|
@@ -2116,7 +2602,7 @@ const en = {
|
|
|
2116
2602
|
signingIn: 'Signing you in…',
|
|
2117
2603
|
ssoHandoff: 'Continue to {{target}}',
|
|
2118
2604
|
// Phone/OTP sign-in labels. `LoginForm` interpolates `{seconds}` with a
|
|
2119
|
-
// literal `.replace()` of its own (
|
|
2605
|
+
// literal `.replace('{seconds}', …)` of its own (in `LoginForm`),
|
|
2120
2606
|
// so those SINGLE braces must survive translation — i18next never sees
|
|
2121
2607
|
// them.
|
|
2122
2608
|
emailOrPhoneLabel: 'Email or phone number',
|
|
@@ -2129,6 +2615,13 @@ const en = {
|
|
|
2129
2615
|
resendOtpCountdownText: 'Resend in {seconds}s',
|
|
2130
2616
|
usePhoneOtpText: 'Sign in with verification code',
|
|
2131
2617
|
usePasswordSignInText: 'Sign in with password instead',
|
|
2618
|
+
// The social provider buttons and the divider under them
|
|
2619
|
+
// (`SocialSignInButtons`, fed through `LoginForm`'s labels).
|
|
2620
|
+
// `{provider}` is the component's own single-brace hole, filled by a
|
|
2621
|
+
// literal `.replace()` with the provider's name as the server reports
|
|
2622
|
+
// it — the same convention as `{seconds}` above (objectui#10900).
|
|
2623
|
+
socialButton: 'Continue with {provider}',
|
|
2624
|
+
orText: 'or continue with email',
|
|
2132
2625
|
devAdminHint: {
|
|
2133
2626
|
title: 'Development instance',
|
|
2134
2627
|
body: 'Sign in with the seeded dev admin:',
|
|
@@ -2157,8 +2650,13 @@ const en = {
|
|
|
2157
2650
|
submittingButton: 'Creating account…',
|
|
2158
2651
|
hasAccountText: 'Already have an account?',
|
|
2159
2652
|
signInText: 'Sign in',
|
|
2653
|
+
// Same pair as `auth.login.socialButton` / `orText`, for sign-up.
|
|
2654
|
+
socialButton: 'Sign up with {provider}',
|
|
2655
|
+
orText: 'or continue with email',
|
|
2160
2656
|
errors: {
|
|
2161
2657
|
userExists: 'An account with this email already exists. Try signing in instead.',
|
|
2658
|
+
selfRegistrationClosed: 'Self-registration is not open on this environment. Ask an administrator for an invitation.',
|
|
2659
|
+
emailDomainNotAllowed: "This email's domain is not allowed to register here. Use your organization email, or ask an administrator for an invitation.",
|
|
2162
2660
|
},
|
|
2163
2661
|
verifyInbox: {
|
|
2164
2662
|
title: 'Check your inbox',
|
|
@@ -2177,7 +2675,7 @@ const en = {
|
|
|
2177
2675
|
submitButton: 'Send Reset Link',
|
|
2178
2676
|
submittingButton: 'Sending…',
|
|
2179
2677
|
successTitle: 'Check your email',
|
|
2180
|
-
successDescription: "We've sent a password reset link to {
|
|
2678
|
+
successDescription: "We've sent a password reset link to {email}. Please check your inbox.",
|
|
2181
2679
|
backToSignInText: 'Back to sign in',
|
|
2182
2680
|
rememberPasswordText: 'Remember your password?',
|
|
2183
2681
|
signInText: 'Sign in',
|
|
@@ -2387,6 +2885,15 @@ const en = {
|
|
|
2387
2885
|
role: 'Role',
|
|
2388
2886
|
save: 'Save Changes',
|
|
2389
2887
|
},
|
|
2888
|
+
language: {
|
|
2889
|
+
title: 'Language',
|
|
2890
|
+
description: 'The language used for notifications and messages sent to you. The interface language is chosen separately, from the globe menu.',
|
|
2891
|
+
label: 'Preferred language',
|
|
2892
|
+
systemDefault: 'Use the deployment default',
|
|
2893
|
+
save: 'Save',
|
|
2894
|
+
saved: 'Language preference updated.',
|
|
2895
|
+
readOnly: 'Your administrator manages the language for your account.',
|
|
2896
|
+
},
|
|
2390
2897
|
password: {
|
|
2391
2898
|
changeTitle: 'Change Password',
|
|
2392
2899
|
setTitle: 'Set Local Password',
|
|
@@ -2418,7 +2925,6 @@ const en = {
|
|
|
2418
2925
|
label: 'Workspaces',
|
|
2419
2926
|
default: 'My Workspace',
|
|
2420
2927
|
switch: 'Switch workspace',
|
|
2421
|
-
create: 'Create workspace',
|
|
2422
2928
|
createTitle: 'Create a workspace',
|
|
2423
2929
|
createDescription: 'A workspace is a shared space for your team to collaborate.',
|
|
2424
2930
|
createButton: 'Create workspace',
|
|
@@ -2441,7 +2947,6 @@ const en = {
|
|
|
2441
2947
|
},
|
|
2442
2948
|
sidebar: {
|
|
2443
2949
|
settings: 'Settings',
|
|
2444
|
-
help: 'Help',
|
|
2445
2950
|
helpTooltip: 'Help & Documentation',
|
|
2446
2951
|
activityFeed: 'Activity feed',
|
|
2447
2952
|
notifications: 'Notifications',
|
|
@@ -2481,7 +2986,6 @@ const en = {
|
|
|
2481
2986
|
},
|
|
2482
2987
|
home: {
|
|
2483
2988
|
title: 'Home',
|
|
2484
|
-
subtitle: 'Your workspace dashboard',
|
|
2485
2989
|
nav: 'Home',
|
|
2486
2990
|
allApps: 'All Applications',
|
|
2487
2991
|
yourApps: 'Your apps',
|
|
@@ -2500,20 +3004,15 @@ const en = {
|
|
|
2500
3004
|
build: {
|
|
2501
3005
|
title: 'Build an app',
|
|
2502
3006
|
subtitle: 'Start from scratch — design objects, forms, automations and interfaces.',
|
|
3007
|
+
noCapability: 'Building apps isn\'t available in this workspace — it requires the “Manage Metadata” permission, which your account doesn\'t have.',
|
|
2503
3008
|
},
|
|
2504
3009
|
template: {
|
|
2505
3010
|
title: 'Start with a template',
|
|
2506
3011
|
subtitle: 'Install a template app from the marketplace and customize it.',
|
|
3012
|
+
marketplaceDisabled: 'This runtime has no app marketplace configured, so there are no templates to install here.',
|
|
2507
3013
|
},
|
|
2508
3014
|
open: 'Open',
|
|
2509
|
-
stats: {
|
|
2510
|
-
apps: 'Applications',
|
|
2511
|
-
starred: 'Starred',
|
|
2512
|
-
recent: 'Recent items',
|
|
2513
|
-
},
|
|
2514
3015
|
loading: 'Loading workspace…',
|
|
2515
|
-
recent: 'Recent',
|
|
2516
|
-
starred: 'Starred',
|
|
2517
3016
|
welcome: 'Build your business system with AI',
|
|
2518
3017
|
welcomeDescription: 'Describe your business in one sentence — AI generates the objects, screens, APIs and agent tools. Or start from scratch.',
|
|
2519
3018
|
welcomeAdminDescription: 'Describe your business in one sentence — AI generates the objects, screens, APIs and agent tools. Or set things up yourself from the menu on the left.',
|
|
@@ -2530,6 +3029,8 @@ const en = {
|
|
|
2530
3029
|
},
|
|
2531
3030
|
pendingDrafts: {
|
|
2532
3031
|
message: 'You have {{count}} unpublished change(s) — publish to make them live.',
|
|
3032
|
+
message_one: 'You have {{count}} unpublished change — publish to make it live.',
|
|
3033
|
+
message_other: 'You have {{count}} unpublished changes — publish to make them live.',
|
|
2533
3034
|
cta: 'Publish',
|
|
2534
3035
|
publishing: 'Publishing…',
|
|
2535
3036
|
published: 'Published! Your changes are live.',
|
|
@@ -2549,8 +3050,6 @@ const en = {
|
|
|
2549
3050
|
browseMarketplace: 'Browse App Marketplace',
|
|
2550
3051
|
quickActions: {
|
|
2551
3052
|
title: 'Quick Actions',
|
|
2552
|
-
createApp: 'Create App',
|
|
2553
|
-
createAppDesc: 'Start with a new application',
|
|
2554
3053
|
manageObjects: 'Manage Objects',
|
|
2555
3054
|
manageObjectsDesc: 'Configure data models',
|
|
2556
3055
|
systemSettings: 'System Settings',
|
|
@@ -2562,7 +3061,9 @@ const en = {
|
|
|
2562
3061
|
object: 'Object',
|
|
2563
3062
|
dashboard: 'Dashboard',
|
|
2564
3063
|
page: 'Page',
|
|
3064
|
+
report: 'Report',
|
|
2565
3065
|
record: 'Record',
|
|
3066
|
+
metadata: 'Metadata',
|
|
2566
3067
|
},
|
|
2567
3068
|
},
|
|
2568
3069
|
starredApps: {
|
|
@@ -2599,7 +3100,6 @@ const en = {
|
|
|
2599
3100
|
organizations: 'Organizations',
|
|
2600
3101
|
roles: 'Roles',
|
|
2601
3102
|
configuration: 'Configuration',
|
|
2602
|
-
createApp: 'Create App',
|
|
2603
3103
|
administration: 'Administration',
|
|
2604
3104
|
datasources: 'Datasources',
|
|
2605
3105
|
documentation: 'Documentation',
|
|
@@ -2614,6 +3114,7 @@ const en = {
|
|
|
2614
3114
|
typeUpdate: 'Update',
|
|
2615
3115
|
typeDelete: 'Delete',
|
|
2616
3116
|
typeComment: 'Comment',
|
|
3117
|
+
typeSystem: 'System',
|
|
2617
3118
|
relativeJustNow: 'just now',
|
|
2618
3119
|
relativeSecondsAgo: '{{count}}s ago',
|
|
2619
3120
|
relativeMinutesAgo: '{{count}}m ago',
|
|
@@ -2634,8 +3135,11 @@ const en = {
|
|
|
2634
3135
|
placeholder: 'Search objects, dashboards, pages, reports…',
|
|
2635
3136
|
inputAriaLabel: 'Search objects, dashboards, pages, reports',
|
|
2636
3137
|
resultsCount: '{{count}} result for "{{query}}"',
|
|
2637
|
-
|
|
3138
|
+
resultsCount_one: '{{count}} result for "{{query}}"',
|
|
3139
|
+
resultsCount_other: '{{count}} results for "{{query}}"',
|
|
2638
3140
|
itemsAvailable: '{{count}} items available',
|
|
3141
|
+
itemsAvailable_one: '{{count}} item available',
|
|
3142
|
+
itemsAvailable_other: '{{count}} items available',
|
|
2639
3143
|
noResults: 'No results found',
|
|
2640
3144
|
noResultsHint: 'Try adjusting your search terms',
|
|
2641
3145
|
typeObjects: 'Objects',
|
|
@@ -2662,7 +3166,11 @@ const en = {
|
|
|
2662
3166
|
noAppsConfigured: 'No Apps Configured',
|
|
2663
3167
|
noAppsConfiguredDescription: 'No applications have been registered. Create your first app or visit System Settings to configure your environment.',
|
|
2664
3168
|
appNotAvailable: 'App not available',
|
|
2665
|
-
appNotAvailableDescription: 'This app is not available
|
|
3169
|
+
appNotAvailableDescription: 'This app is not available — try again in a moment.',
|
|
3170
|
+
appNotFound: "This app can't be opened",
|
|
3171
|
+
appNotFoundDescription: 'The server did not return this app for your account.',
|
|
3172
|
+
appUnreachable: "Couldn't reach the server",
|
|
3173
|
+
appUnreachableDescription: 'This app could not be checked. Try again in a moment.',
|
|
2666
3174
|
appAccessDenied: "You don't have access to this app",
|
|
2667
3175
|
appAccessDeniedDescription: 'This app exists, but your account is not authorized to open it. Ask an administrator to grant you access.',
|
|
2668
3176
|
appAccessDeniedHome: 'Back to home',
|
|
@@ -2706,7 +3214,16 @@ const en = {
|
|
|
2706
3214
|
detailNone: 'No differences detected — the draft matches the published version.',
|
|
2707
3215
|
detailChangedKeys: 'Also changed:',
|
|
2708
3216
|
confirmNote: 'Publishing releases all {{count}} pending drafts of this package atomically.',
|
|
3217
|
+
confirmNote_one: 'Publishing releases the {{count}} pending draft of this package atomically.',
|
|
3218
|
+
confirmNote_other: 'Publishing releases all {{count}} pending drafts of this package atomically.',
|
|
2709
3219
|
publishConfirm: 'Publish all',
|
|
3220
|
+
// [`7a90afdf9`] Pre-publish security-posture findings, shown next to
|
|
3221
|
+
// the confirm button so a refusal the door would issue is read BEFORE
|
|
3222
|
+
// the click rather than as a toast after the batch rolled back.
|
|
3223
|
+
securityBlockTitle: 'Publishing will be refused — {{count}} item(s) need a decision first',
|
|
3224
|
+
securityBlockTitle_one: 'Publishing will be refused — {{count}} item needs a decision first',
|
|
3225
|
+
securityBlockTitle_other: 'Publishing will be refused — {{count}} items need a decision first',
|
|
3226
|
+
securityBlockWhere: 'Fix it on the object under Settings → Record sharing, then publish again.',
|
|
2710
3227
|
},
|
|
2711
3228
|
// ADR-0045 — the materialized-but-unlisted app banner
|
|
2712
3229
|
// (UnpublishedAppBar.tsx), sibling of draftBar above.
|
|
@@ -2733,7 +3250,19 @@ const en = {
|
|
|
2733
3250
|
revertLabel: 'Reverted a change',
|
|
2734
3251
|
applyLabel: 'Build change',
|
|
2735
3252
|
revert: 'revert',
|
|
2736
|
-
|
|
3253
|
+
// objectui#9266 — the count is INSIDE the value, one interpolated string
|
|
3254
|
+
// per pack. It used to be a bare unit word that `CommitTimeline` glued to
|
|
3255
|
+
// a number it rendered itself, which no pack could make agree: `de` read
|
|
3256
|
+
// `1 Elemente`, `ru` `1 элементов`, `ar` `1 عناصر`. Each pack now states
|
|
3257
|
+
// the count in its own count-INVARIANT idiom — `en` keeps the `(s)` marker
|
|
3258
|
+
// it already dodged with, `zh`/`ja`/`ko` keep the inline counter their
|
|
3259
|
+
// grammar needs no plural for, and `de`/`fr`/`es`/`pt`/`ru`/`ar` use the
|
|
3260
|
+
// label-colon form (`Elemente: 3`, `Элементов: 3`), which is the shape
|
|
3261
|
+
// `fields.textarea.charactersRemaining` already uses for this exact
|
|
3262
|
+
// reason. It needs no family: every pack's form reads at any number,
|
|
3263
|
+
// which is why `count-families-11445.test.ts` names it on its
|
|
3264
|
+
// count-neutral list rather than holding it to the family rule.
|
|
3265
|
+
items: '{{count}} item(s)',
|
|
2737
3266
|
revertAction: 'Revert',
|
|
2738
3267
|
reverted: 'Reverted — the change has been undone.',
|
|
2739
3268
|
revertFailed: 'Revert failed',
|
|
@@ -2742,21 +3271,6 @@ const en = {
|
|
|
2742
3271
|
revertUnavailable: 'Commit store temporarily unreachable — the revert may not have been applied. Reopen this history to check before retrying.',
|
|
2743
3272
|
},
|
|
2744
3273
|
},
|
|
2745
|
-
renderer: {
|
|
2746
|
-
noPageSchema: 'No page schema provided',
|
|
2747
|
-
noFormSchema: 'No form schema provided',
|
|
2748
|
-
noDashboardSchema: 'No dashboard schema provided',
|
|
2749
|
-
pageRendering: 'Page rendering: {{name}}',
|
|
2750
|
-
dashboardRendering: 'Dashboard rendering: {{name}}',
|
|
2751
|
-
formRenderingMode: 'Form rendering in {{mode}} mode',
|
|
2752
|
-
formRenderingFor: 'for record {{id}}',
|
|
2753
|
-
createRecord: 'Create Record',
|
|
2754
|
-
editRecord: 'Edit Record',
|
|
2755
|
-
page: 'Page',
|
|
2756
|
-
dashboard: 'Dashboard',
|
|
2757
|
-
save: 'Save',
|
|
2758
|
-
cancel: 'Cancel',
|
|
2759
|
-
},
|
|
2760
3274
|
actionDialog: {
|
|
2761
3275
|
title: 'Action Parameters',
|
|
2762
3276
|
description: 'Please provide the required information to continue.',
|
|
@@ -2764,22 +3278,17 @@ const en = {
|
|
|
2764
3278
|
requiredError: '{{label}} is required',
|
|
2765
3279
|
lookupPlaceholder: 'Record id for {{label}}',
|
|
2766
3280
|
lookupHelpText: 'No reference object is configured for this parameter, so the record picker is unavailable. Enter a record id, or ask an administrator to fix the action parameter.',
|
|
3281
|
+
unresolvedParam: 'This parameter cannot be shown: the field it is backed by is missing from the object metadata, so the control it needs cannot be built. Ask an administrator to fix the action definition.',
|
|
3282
|
+
carryOverHint: 'Carried over unchanged (read-only)',
|
|
2767
3283
|
cancel: 'Cancel',
|
|
2768
3284
|
confirm: 'Confirm',
|
|
2769
3285
|
uploading: 'Uploading…',
|
|
2770
|
-
defaultActionTitle: 'Action',
|
|
2771
|
-
ok: 'OK',
|
|
2772
3286
|
},
|
|
2773
3287
|
actionConfirm: {
|
|
2774
3288
|
title: 'Confirm Action',
|
|
2775
3289
|
confirm: 'Continue',
|
|
2776
3290
|
cancel: 'Cancel',
|
|
2777
3291
|
},
|
|
2778
|
-
rowAction: {
|
|
2779
|
-
openMenu: 'Open menu',
|
|
2780
|
-
edit: 'Edit',
|
|
2781
|
-
delete: 'Delete',
|
|
2782
|
-
},
|
|
2783
3292
|
navigationSync: {
|
|
2784
3293
|
addedPage: 'Navigation updated: added page "{{name}}"',
|
|
2785
3294
|
addedDashboard: 'Navigation updated: added dashboard "{{name}}"',
|
|
@@ -2801,6 +3310,8 @@ const en = {
|
|
|
2801
3310
|
'Deleting resets it to the shipped baseline and discards your environment customization. Continue?',
|
|
2802
3311
|
resetPackageSetSuccess: 'Permission set reset to its shipped baseline',
|
|
2803
3312
|
bulkDeleteSuccess: 'Deleted {{count}} {{label}} records',
|
|
3313
|
+
bulkDeleteSuccess_one: 'Deleted {{count}} {{label}} record',
|
|
3314
|
+
bulkDeleteSuccess_other: 'Deleted {{count}} {{label}} records',
|
|
2804
3315
|
bulkDeletePartial: '{{succeeded}} deleted, {{failed}} failed',
|
|
2805
3316
|
},
|
|
2806
3317
|
objectViewActions: {
|
|
@@ -2812,15 +3323,6 @@ const en = {
|
|
|
2812
3323
|
exportFailed: 'Export failed: {{message}}',
|
|
2813
3324
|
forecastSoon: 'Forecast view coming soon',
|
|
2814
3325
|
},
|
|
2815
|
-
recordDetail: {
|
|
2816
|
-
viewersTooltip: 'Users viewing this record',
|
|
2817
|
-
},
|
|
2818
|
-
cellRender: {
|
|
2819
|
-
empty: 'Empty',
|
|
2820
|
-
yes: 'Yes',
|
|
2821
|
-
no: 'No',
|
|
2822
|
-
systemFields: 'System',
|
|
2823
|
-
},
|
|
2824
3326
|
user: {
|
|
2825
3327
|
profile: 'Profile',
|
|
2826
3328
|
settings: 'Settings',
|
|
@@ -2979,6 +3481,9 @@ const en = {
|
|
|
2979
3481
|
declined: 'Invitation declined',
|
|
2980
3482
|
declineFailed: 'Failed to decline invitation',
|
|
2981
3483
|
},
|
|
3484
|
+
current: {
|
|
3485
|
+
label: 'Current organization',
|
|
3486
|
+
},
|
|
2982
3487
|
switcher: {
|
|
2983
3488
|
label: 'Switch organization',
|
|
2984
3489
|
groupLabel: 'Working organization',
|
|
@@ -2996,18 +3501,35 @@ const en = {
|
|
|
2996
3501
|
viewAll: 'View all notifications',
|
|
2997
3502
|
groupCount: '{{count}} notifications',
|
|
2998
3503
|
groupUnread: '{{count}} unread',
|
|
3504
|
+
groupUnread_one: '{{count}} unread',
|
|
3505
|
+
groupUnread_other: '{{count}} unread',
|
|
2999
3506
|
groupMarkRead: 'Mark read',
|
|
3000
3507
|
groupMarkReadTitle: 'Mark all of this type read',
|
|
3001
3508
|
approvalsPending: '{{count}} pending approvals',
|
|
3509
|
+
approvalsPending_one: '{{count}} pending approval',
|
|
3510
|
+
approvalsPending_other: '{{count}} pending approvals',
|
|
3002
3511
|
viewApprovals: 'View approvals',
|
|
3003
3512
|
noPendingApprovals: 'No pending approvals',
|
|
3004
3513
|
openApprovalsInbox: 'Open Approvals Inbox',
|
|
3005
|
-
// Bell-badge breakdown (#7233): the badge sums unread notification topics
|
|
3514
|
+
// Bell-badge breakdown (objectstack-ai/objectstack#7233): the badge sums unread notification topics
|
|
3006
3515
|
// and pending approvals, then clamps at "9+". These three spell the sum
|
|
3007
3516
|
// out inside the popover so the number is explainable.
|
|
3008
3517
|
badgeTotal: '{{total}} total',
|
|
3009
3518
|
badgeNotifications: '{{unread}} notifications',
|
|
3010
3519
|
badgeApprovals: '{{approvals}} pending approvals',
|
|
3520
|
+
// objectui#7011 — the arrival announcement (toast / desktop notification)
|
|
3521
|
+
// and the two switches that govern it.
|
|
3522
|
+
arrivalMany: '{{count}} new messages',
|
|
3523
|
+
arrivalMany_one: '{{count}} new message',
|
|
3524
|
+
arrivalMany_other: '{{count}} new messages',
|
|
3525
|
+
arrivalRepeats: '{{count}} new messages on this topic',
|
|
3526
|
+
arrivalRepeats_one: '{{count}} new message on this topic',
|
|
3527
|
+
arrivalRepeats_other: '{{count}} new messages on this topic',
|
|
3528
|
+
arrivalOpen: 'View',
|
|
3529
|
+
toastEnabled: 'In-app alerts',
|
|
3530
|
+
desktopEnabled: 'Desktop notifications',
|
|
3531
|
+
desktopBlocked: 'Blocked. Allow notifications for this site in your browser settings.',
|
|
3532
|
+
desktopUnsupported: 'This browser does not support desktop notifications.',
|
|
3011
3533
|
},
|
|
3012
3534
|
publicForm: {
|
|
3013
3535
|
submit: 'Submit',
|
|
@@ -3018,63 +3540,25 @@ const en = {
|
|
|
3018
3540
|
thankYouTitle: 'Thank you!',
|
|
3019
3541
|
thankYouMessage: 'Your submission has been received successfully.',
|
|
3020
3542
|
redirecting: 'Redirecting in {{seconds}} seconds…',
|
|
3543
|
+
// The console form page's line for a submit whose declared redirect is
|
|
3544
|
+
// pending (objectui#11071). `redirecting` above is the embeddable form's
|
|
3545
|
+
// countdown and carries a `{{seconds}}` hole this page has no value for.
|
|
3546
|
+
redirectPending: 'Redirecting…',
|
|
3021
3547
|
unavailableTitle: 'Form unavailable',
|
|
3022
3548
|
unavailableDescription: 'No public form is available at this URL. Make sure the underlying view has anonymous sharing enabled and matches this slug.',
|
|
3023
3549
|
tryDemo: 'Try the demo',
|
|
3024
3550
|
retry: 'Retry',
|
|
3025
3551
|
loading: 'Loading form…',
|
|
3026
3552
|
requiredHint: '* Required field',
|
|
3553
|
+
// The console form page's client-side refusal when required rows are empty
|
|
3554
|
+
// (objectui#11071). `{{fields}}` is the empty rows' labels joined with a
|
|
3555
|
+
// comma; the colon, its spacing and the order are the pack's.
|
|
3556
|
+
requiredFields: 'Required: {{fields}}',
|
|
3027
3557
|
consentLabelDefault: 'I agree to the privacy policy and consent to my data being processed for this request.',
|
|
3028
3558
|
consentLink: 'Privacy policy',
|
|
3029
3559
|
consentRequired: 'Please accept the privacy policy to continue.',
|
|
3030
3560
|
rateLimited: 'Please take a moment to review your answers before submitting.',
|
|
3031
3561
|
redirectBlocked: 'Submission accepted, but the redirect URL was blocked for security.',
|
|
3032
|
-
demo: {
|
|
3033
|
-
contactTitle: 'Contact us',
|
|
3034
|
-
contactDescription: 'Tell us about your project and a sales representative will get back to you within one business day.',
|
|
3035
|
-
supportTitle: 'Submit a support request',
|
|
3036
|
-
supportDescription: 'Tell us what is going wrong — our team responds within one business day.',
|
|
3037
|
-
thankYouSalesTitle: 'Thanks — we received your message!',
|
|
3038
|
-
thankYouSalesMessage: 'A sales representative will be in touch within one business day.',
|
|
3039
|
-
thankYouSupportTitle: 'Got it — your request is in the queue.',
|
|
3040
|
-
thankYouSupportMessage: 'A support engineer will follow up shortly. Save this page if you have more screenshots to add.',
|
|
3041
|
-
field: {
|
|
3042
|
-
firstName: 'First name',
|
|
3043
|
-
lastName: 'Last name',
|
|
3044
|
-
email: 'Work email',
|
|
3045
|
-
phone: 'Phone',
|
|
3046
|
-
jobTitle: 'Job title',
|
|
3047
|
-
company: 'Company',
|
|
3048
|
-
website: 'Website',
|
|
3049
|
-
industry: 'Industry',
|
|
3050
|
-
companySize: 'Company size',
|
|
3051
|
-
howCanWeHelp: 'How can we help?',
|
|
3052
|
-
subject: 'Subject',
|
|
3053
|
-
description: 'Description',
|
|
3054
|
-
issueType: 'Issue type',
|
|
3055
|
-
priority: 'Priority',
|
|
3056
|
-
},
|
|
3057
|
-
industry: {
|
|
3058
|
-
technology: 'Technology',
|
|
3059
|
-
software: 'Software / SaaS',
|
|
3060
|
-
finance: 'Finance',
|
|
3061
|
-
healthcare: 'Healthcare',
|
|
3062
|
-
retail: 'Retail',
|
|
3063
|
-
other: 'Other',
|
|
3064
|
-
},
|
|
3065
|
-
issueType: {
|
|
3066
|
-
question: 'Question',
|
|
3067
|
-
problem: 'Problem',
|
|
3068
|
-
bug: 'Bug',
|
|
3069
|
-
feature_request: 'Feature request',
|
|
3070
|
-
},
|
|
3071
|
-
priority: {
|
|
3072
|
-
low: 'Low',
|
|
3073
|
-
medium: 'Medium',
|
|
3074
|
-
high: 'High',
|
|
3075
|
-
critical: 'Critical',
|
|
3076
|
-
},
|
|
3077
|
-
},
|
|
3078
3562
|
},
|
|
3079
3563
|
connectAgent: {
|
|
3080
3564
|
disabled: {
|
|
@@ -3120,6 +3604,8 @@ const en = {
|
|
|
3120
3604
|
noImportableFields: 'That object has no importable fields.',
|
|
3121
3605
|
schemaReadFailed: 'Could not read the object schema.',
|
|
3122
3606
|
imported: 'Imported {{count}} row(s) into {{object}}.',
|
|
3607
|
+
imported_one: 'Imported {{count}} row into {{object}}.',
|
|
3608
|
+
imported_other: 'Imported {{count}} rows into {{object}}.',
|
|
3123
3609
|
importFrom: 'Import the real rows from',
|
|
3124
3610
|
into: 'into',
|
|
3125
3611
|
opening: 'Opening…',
|
|
@@ -3133,6 +3619,88 @@ const en = {
|
|
|
3133
3619
|
openProduction: 'Open Production',
|
|
3134
3620
|
manageEnvironments: 'Manage environments',
|
|
3135
3621
|
},
|
|
3622
|
+
// `cloud:plan-status` — the Cloud pricing page's current-plan marker (objectui#10919).
|
|
3623
|
+
cloudPlanStatus: {
|
|
3624
|
+
current: 'Current plan',
|
|
3625
|
+
},
|
|
3626
|
+
// `@object-ui/plugin-ai` — the `nl-query`, `ai-form-assist` and
|
|
3627
|
+
// `ai-recommendations` components (objectui#10232). The two count labels are
|
|
3628
|
+
// i18next count families (objectui#11445): the component passes `count` and
|
|
3629
|
+
// each pack carries every CLDR category its language selects.
|
|
3630
|
+
ai: {
|
|
3631
|
+
nlQuery: {
|
|
3632
|
+
placeholder: 'Ask a question about your data…',
|
|
3633
|
+
ask: 'Ask',
|
|
3634
|
+
results: 'Results',
|
|
3635
|
+
match: '{{percent}} match',
|
|
3636
|
+
simulatedSummary: 'Results for: {{query}}',
|
|
3637
|
+
noResults: 'No matching records found',
|
|
3638
|
+
recentQueries: 'Recent Queries',
|
|
3639
|
+
},
|
|
3640
|
+
formAssist: {
|
|
3641
|
+
title: 'AI Suggestions',
|
|
3642
|
+
suggestionCount: '{{count}} suggestions',
|
|
3643
|
+
suggestionCount_one: '{{count}} suggestion',
|
|
3644
|
+
suggestionCount_other: '{{count}} suggestions',
|
|
3645
|
+
applyAll: 'Apply All',
|
|
3646
|
+
confidence: '{{percent}} confidence',
|
|
3647
|
+
appliedCount: '{{count}} suggestions applied',
|
|
3648
|
+
appliedCount_one: '{{count}} suggestion applied',
|
|
3649
|
+
appliedCount_other: '{{count}} suggestions applied',
|
|
3650
|
+
},
|
|
3651
|
+
recommendations: {
|
|
3652
|
+
title: 'Recommendations',
|
|
3653
|
+
generating: 'Generating recommendations…',
|
|
3654
|
+
empty: 'No recommendations available',
|
|
3655
|
+
},
|
|
3656
|
+
},
|
|
3657
|
+
// The AI HITL approval inbox (`@object-ui/plugin-chatbot`'s
|
|
3658
|
+
// `AiPendingActionsInbox`) — objectui#7173. Its four relative-time phrases
|
|
3659
|
+
// are NOT here: it borrows `detail.justNow` / `minutesAgo` / `hoursAgo` /
|
|
3660
|
+
// `daysAgo`, already translated in all ten packs, the way `ObjectGrid` and
|
|
3661
|
+
// `ObjectKanban` borrow `detail.recordDetail`. Distinct from
|
|
3662
|
+
// `approvalsInbox` above, which is the human approval-PROCESS inbox:
|
|
3663
|
+
// different surface, different feature, so no rows are shared with it.
|
|
3664
|
+
aiApprovals: {
|
|
3665
|
+
title: 'AI Approvals',
|
|
3666
|
+
description: 'Actions an AI agent proposed that need a human review before execution.',
|
|
3667
|
+
tabPending: 'Pending',
|
|
3668
|
+
tabDecided: 'Decided',
|
|
3669
|
+
tabAll: 'All',
|
|
3670
|
+
statusPending: 'Pending',
|
|
3671
|
+
statusApproved: 'Approved',
|
|
3672
|
+
statusExecuted: 'Executed',
|
|
3673
|
+
statusFailed: 'Failed',
|
|
3674
|
+
statusRejected: 'Rejected',
|
|
3675
|
+
colTool: 'Tool',
|
|
3676
|
+
colAction: 'Action',
|
|
3677
|
+
colObject: 'Object',
|
|
3678
|
+
colStatus: 'Status',
|
|
3679
|
+
colProposed: 'Proposed',
|
|
3680
|
+
colDecision: 'Decision',
|
|
3681
|
+
emptyTitle: 'No actions waiting',
|
|
3682
|
+
emptyDescription: 'When the AI proposes a sensitive action it will appear here for review.',
|
|
3683
|
+
view: 'View',
|
|
3684
|
+
approve: 'Approve',
|
|
3685
|
+
reject: 'Reject',
|
|
3686
|
+
working: 'Working…',
|
|
3687
|
+
approveAndExecute: 'Approve & Execute',
|
|
3688
|
+
outcomeApprove: 'Approve for {{id}}: {{message}}',
|
|
3689
|
+
outcomeReject: 'Reject for {{id}}: {{message}}',
|
|
3690
|
+
outcomeExecuteFailed: 'Action failed during execution',
|
|
3691
|
+
drawerFallbackTitle: 'Pending action',
|
|
3692
|
+
drawerSubtitle: 'Tool {{tool}} on {{object}}',
|
|
3693
|
+
fieldProposedBy: 'Proposed by',
|
|
3694
|
+
fieldDecidedBy: 'Decided by',
|
|
3695
|
+
fieldConversation: 'Conversation',
|
|
3696
|
+
fieldToolInput: 'Tool input',
|
|
3697
|
+
fieldResult: 'Result',
|
|
3698
|
+
fieldError: 'Error',
|
|
3699
|
+
fieldRejectionReason: 'Rejection reason',
|
|
3700
|
+
rejectTitle: 'Reject this action?',
|
|
3701
|
+
rejectBody: 'The reason is shown back to the AI so it can adjust its next response.',
|
|
3702
|
+
rejectPlaceholder: "Optional reason (e.g. 'Wrong record id — please confirm with the user first.')",
|
|
3703
|
+
},
|
|
3136
3704
|
aiModelStatus: {
|
|
3137
3705
|
summary: 'Build / Ask uses {{conversational}} ({{conversationalSource}}); structured uses {{structured}} ({{structuredSource}}).',
|
|
3138
3706
|
summaryRouting: 'Routing policy: free plans → {{free}}, paid plans → {{paid}}.',
|
|
@@ -3150,6 +3718,118 @@ const en = {
|
|
|
3150
3718
|
sourceInherits: 'same as build/ask',
|
|
3151
3719
|
sourcePinned: 'pinned by {{source}}',
|
|
3152
3720
|
},
|
|
3721
|
+
// objectui#7254 — the AI copilot's tool cards. Three families, all of them
|
|
3722
|
+
// English-only until this landed while every other string on the same screen
|
|
3723
|
+
// was translated:
|
|
3724
|
+
//
|
|
3725
|
+
// `tool.*` — one entry per PLATFORM-PROVIDED tool name
|
|
3726
|
+
// (@objectstack/spec `PLATFORM_TOOLS_BY_PACKAGE`, the
|
|
3727
|
+
// closed registry those runtimes are conformance-tested
|
|
3728
|
+
// against). `humanizeToolName` looks each up as
|
|
3729
|
+
// `chatbot.tool.<tool_name>` and falls back to its English
|
|
3730
|
+
// title-caser for a custom / third-party tool, so a name
|
|
3731
|
+
// missing here is degraded, never broken. The `en` values
|
|
3732
|
+
// are deliberately EQUAL to what that title-caser produces:
|
|
3733
|
+
// adding the key must not silently reword the English UI.
|
|
3734
|
+
// `toolState.*` — the card-header badge + activity-chip vocabulary. ONE
|
|
3735
|
+
// set for both surfaces (they used to carry separate
|
|
3736
|
+
// tables and disagreed on casing).
|
|
3737
|
+
// `build.*` — the apply_blueprint BUILD PANEL's own copy (objectui#7388).
|
|
3738
|
+
// Everything else on that panel is fed by the host as an
|
|
3739
|
+
// already-translated prop; these strings were literals in
|
|
3740
|
+
// the component, so they stayed English in every language.
|
|
3741
|
+
// `building`/`built` interpolate `appFallback` when the
|
|
3742
|
+
// build has no app label, so each pack must keep BOTH
|
|
3743
|
+
// frames in the one case/gender that noun phrase is in.
|
|
3744
|
+
// `plan.*` — the "N objects · N views · N dashboards" strip. Plural
|
|
3745
|
+
// FAMILIES: one slot per CLDR category the pack's language
|
|
3746
|
+
// selects (objectui#11432), plus the base key for a call
|
|
3747
|
+
// made without a count. `all-locales-key-parity.test.ts`
|
|
3748
|
+
// derives the required slots from `Intl.PluralRules`.
|
|
3749
|
+
//
|
|
3750
|
+
// objectui#7481 — five `tool.*` entries are NEWER than the registry above:
|
|
3751
|
+
// `get_authoring_rules` (cloud#1837), `load_tools`, `open_record`, `test_flow`
|
|
3752
|
+
// and `toggle_flow` are registered by cloud `service-ai-studio` but the pinned
|
|
3753
|
+
// `@objectstack/spec` snapshot does not list them yet. They are kept here on
|
|
3754
|
+
// purpose: a step label the user reads must not wait on a pin bump. When the
|
|
3755
|
+
// pin advances, `chatbotToolLabels-locale-parity-7481` starts checking them
|
|
3756
|
+
// against the registry instead of against its own hand-held list.
|
|
3757
|
+
chatbot: {
|
|
3758
|
+
tool: {
|
|
3759
|
+
aggregate_data: 'Aggregate data',
|
|
3760
|
+
get_record: 'Get record',
|
|
3761
|
+
query_data: 'Query data',
|
|
3762
|
+
query_records: 'Query records',
|
|
3763
|
+
search_knowledge: 'Search knowledge',
|
|
3764
|
+
visualize_data: 'Visualize data',
|
|
3765
|
+
add_field: 'Add field',
|
|
3766
|
+
apply_blueprint: 'Apply blueprint',
|
|
3767
|
+
apply_edit: 'Apply edit',
|
|
3768
|
+
create_metadata: 'Create metadata',
|
|
3769
|
+
create_object: 'Create object',
|
|
3770
|
+
create_package: 'Create package',
|
|
3771
|
+
create_seed: 'Create seed',
|
|
3772
|
+
delete_field: 'Delete field',
|
|
3773
|
+
describe_metadata: 'Describe metadata',
|
|
3774
|
+
describe_object: 'Describe object',
|
|
3775
|
+
get_active_package: 'Get active package',
|
|
3776
|
+
get_authoring_rules: 'Get authoring rules',
|
|
3777
|
+
get_metadata_schema: 'Get metadata schema',
|
|
3778
|
+
get_package: 'Get package',
|
|
3779
|
+
list_metadata: 'List metadata',
|
|
3780
|
+
list_objects: 'List objects',
|
|
3781
|
+
list_packages: 'List packages',
|
|
3782
|
+
load_tools: 'Load tools',
|
|
3783
|
+
modify_field: 'Modify field',
|
|
3784
|
+
open_record: 'Open record',
|
|
3785
|
+
propose_blueprint: 'Propose blueprint',
|
|
3786
|
+
set_active_package: 'Set active package',
|
|
3787
|
+
suggest_builder: 'Suggest builder',
|
|
3788
|
+
test_flow: 'Test flow',
|
|
3789
|
+
todo_write: 'Todo write',
|
|
3790
|
+
toggle_flow: 'Toggle flow',
|
|
3791
|
+
update_metadata: 'Update metadata',
|
|
3792
|
+
validate_expression: 'Validate expression',
|
|
3793
|
+
verify_build: 'Verify build',
|
|
3794
|
+
},
|
|
3795
|
+
toolState: {
|
|
3796
|
+
agentActivity: 'Agent activity',
|
|
3797
|
+
pending: 'Pending',
|
|
3798
|
+
running: 'Running',
|
|
3799
|
+
awaitingApproval: 'Awaiting approval',
|
|
3800
|
+
responded: 'Responded',
|
|
3801
|
+
completed: 'Completed',
|
|
3802
|
+
error: 'Error',
|
|
3803
|
+
denied: 'Denied',
|
|
3804
|
+
failed: 'Failed',
|
|
3805
|
+
},
|
|
3806
|
+
plan: {
|
|
3807
|
+
countObjects: '{{count}} objects',
|
|
3808
|
+
countObjects_one: '{{count}} object',
|
|
3809
|
+
countObjects_other: '{{count}} objects',
|
|
3810
|
+
countViews: '{{count}} views',
|
|
3811
|
+
countViews_one: '{{count}} view',
|
|
3812
|
+
countViews_other: '{{count}} views',
|
|
3813
|
+
countDashboards: '{{count}} dashboards',
|
|
3814
|
+
countDashboards_one: '{{count}} dashboard',
|
|
3815
|
+
countDashboards_other: '{{count}} dashboards',
|
|
3816
|
+
countSeedData: 'sample data',
|
|
3817
|
+
},
|
|
3818
|
+
build: {
|
|
3819
|
+
building: 'Building {{app}}…',
|
|
3820
|
+
built: 'Built {{app}}',
|
|
3821
|
+
appFallback: 'your app',
|
|
3822
|
+
addingSampleData: 'adding sample data',
|
|
3823
|
+
group: {
|
|
3824
|
+
object: 'Objects',
|
|
3825
|
+
view: 'Views',
|
|
3826
|
+
dashboard: 'Dashboards',
|
|
3827
|
+
app: 'App',
|
|
3828
|
+
seed: 'Sample data',
|
|
3829
|
+
},
|
|
3830
|
+
moreArtifacts: '+{{n}} more',
|
|
3831
|
+
},
|
|
3832
|
+
},
|
|
3153
3833
|
chatbotError: {
|
|
3154
3834
|
title: 'Response failed',
|
|
3155
3835
|
fallbackDetail: 'Something went wrong. Please try again.',
|
|
@@ -3188,6 +3868,7 @@ const en = {
|
|
|
3188
3868
|
retry: 'Try again',
|
|
3189
3869
|
errors: {
|
|
3190
3870
|
expired: 'The request expired before it was approved. Start again.',
|
|
3871
|
+
accessDenied: 'The connection request was denied. Start again.',
|
|
3191
3872
|
bindFailed: 'Binding failed.',
|
|
3192
3873
|
deviceCodeFailed: 'Device code request failed.',
|
|
3193
3874
|
},
|
|
@@ -3221,7 +3902,7 @@ const en = {
|
|
|
3221
3902
|
marketplace: {
|
|
3222
3903
|
title: 'App Marketplace',
|
|
3223
3904
|
subtitle: 'Browse approved apps published to the ObjectStack catalog. Click an app to view details and install it into one of your environments.',
|
|
3224
|
-
searchPlaceholder: 'Search apps by name or
|
|
3905
|
+
searchPlaceholder: 'Search apps by name or app ID…',
|
|
3225
3906
|
searchAria: 'Search marketplace apps',
|
|
3226
3907
|
installed: 'Installed',
|
|
3227
3908
|
installedCount: 'Installed ({{count}})',
|
|
@@ -3244,10 +3925,16 @@ const en = {
|
|
|
3244
3925
|
installedBadge: 'Installed v{{version}}',
|
|
3245
3926
|
load: {
|
|
3246
3927
|
failed: 'Failed to load marketplace',
|
|
3247
|
-
|
|
3928
|
+
failedHintConfigured: 'This runtime reaches the marketplace through the control plane at {{url}}. Check that it is online and reachable from here.',
|
|
3929
|
+
failedHintSameOrigin: 'This runtime serves the marketplace catalog itself. Check that the runtime is online.',
|
|
3248
3930
|
packageFailed: 'Failed to load package',
|
|
3249
3931
|
notFound: 'Not found.',
|
|
3250
3932
|
},
|
|
3933
|
+
disabled: {
|
|
3934
|
+
title: 'App Marketplace is turned off',
|
|
3935
|
+
description: 'This runtime has no marketplace configured, so there is nothing to browse or install from here.',
|
|
3936
|
+
hint: 'That is the expected state when the runtime is started with <code>OS_CLOUD_URL=off</code> (or <code>none</code>, <code>local</code>, <code>disabled</code>). To turn the marketplace on, point <code>OS_CLOUD_URL</code> at a control plane and restart the runtime.',
|
|
3937
|
+
},
|
|
3251
3938
|
detail: {
|
|
3252
3939
|
homepage: 'Homepage',
|
|
3253
3940
|
installedV: 'Installed · v{{version}}',
|
|
@@ -3263,10 +3950,15 @@ const en = {
|
|
|
3263
3950
|
purgeSampleData: 'Purge sample data',
|
|
3264
3951
|
purgeConfirm: 'Delete all sample records seeded by this package? User-added records will NOT be touched.',
|
|
3265
3952
|
purgeSuccess: 'Removed {{count}} sample record(s).',
|
|
3953
|
+
purgeSuccess_one: 'Removed {{count}} sample record.',
|
|
3954
|
+
purgeSuccess_other: 'Removed {{count}} sample records.',
|
|
3266
3955
|
purgeNoData: 'No sample records found to purge.',
|
|
3267
3956
|
reseedQueued: 'Sample data will be re-seeded on next environment access.',
|
|
3268
3957
|
reseedLocalSuccess: 'Re-seeded sample data: {{inserted}} inserted, {{updated}} updated.',
|
|
3269
3958
|
reseedPartialErrors: '({{count}} record(s) failed to write)',
|
|
3959
|
+
reseedPartialErrors_one: '({{count}} record failed to write)',
|
|
3960
|
+
reseedPartialErrors_other: '({{count}} records failed to write)',
|
|
3961
|
+
sampleDataKernelUnavailable: 'This control plane has no environment kernel, so sample data cannot be re-seeded or purged from here. Do it from the environment\'s own runtime.',
|
|
3270
3962
|
updateAvailable: 'Update available',
|
|
3271
3963
|
},
|
|
3272
3964
|
action: {
|
|
@@ -3319,7 +4011,8 @@ const en = {
|
|
|
3319
4011
|
reviewed: 'Reviewed & approved',
|
|
3320
4012
|
unreviewed: 'Not yet reviewed',
|
|
3321
4013
|
signed: 'Signed',
|
|
3322
|
-
grantsIntro: '
|
|
4014
|
+
grantsIntro: 'This package requests:',
|
|
4015
|
+
notEnforced: 'Recorded at install, and re-confirmed if a later version asks for more — but the runtime does not yet restrict the package to this list.',
|
|
3323
4016
|
services: 'Platform services',
|
|
3324
4017
|
hooks: 'Lifecycle hooks',
|
|
3325
4018
|
network: 'Network access',
|
|
@@ -3370,30 +4063,19 @@ const en = {
|
|
|
3370
4063
|
storage: 'Storage',
|
|
3371
4064
|
other: 'Other',
|
|
3372
4065
|
},
|
|
3373
|
-
pricing: {
|
|
3374
|
-
free: 'Free',
|
|
3375
|
-
freemium: 'Freemium',
|
|
3376
|
-
paid: 'Paid',
|
|
3377
|
-
subscription: 'Subscription',
|
|
3378
|
-
'usage-based': 'Usage-based',
|
|
3379
|
-
'contact-sales': 'Contact Sales',
|
|
3380
|
-
},
|
|
3381
4066
|
relativeTime: {
|
|
3382
4067
|
today: 'today',
|
|
3383
4068
|
daysAgo: '{{count}}d ago',
|
|
3384
4069
|
monthsAgo: '{{count}}mo ago',
|
|
4070
|
+
monthsAgo_one: '{{count}}mo ago',
|
|
4071
|
+
monthsAgo_other: '{{count}}mo ago',
|
|
3385
4072
|
yearsAgo: '{{count}}y ago',
|
|
4073
|
+
yearsAgo_one: '{{count}}y ago',
|
|
4074
|
+
yearsAgo_other: '{{count}}y ago',
|
|
3386
4075
|
},
|
|
3387
4076
|
},
|
|
3388
|
-
approvals: {
|
|
3389
|
-
approve: 'Approve',
|
|
3390
|
-
reject: 'Reject',
|
|
3391
|
-
comment: 'Comment (optional)',
|
|
3392
|
-
approveSuccess: 'Approved',
|
|
3393
|
-
rejectSuccess: 'Rejected',
|
|
3394
|
-
rejectConfirm: 'Reject this approval request?',
|
|
3395
|
-
},
|
|
3396
4077
|
approvalsInbox: {
|
|
4078
|
+
recordUnresolvable: 'This record cannot be opened',
|
|
3397
4079
|
loadMore: 'Load more',
|
|
3398
4080
|
loadingMore: 'Loading…',
|
|
3399
4081
|
loadedOf: 'Loaded {{loaded}} of {{total}}',
|
|
@@ -3412,6 +4094,8 @@ const en = {
|
|
|
3412
4094
|
requestInfoSent: 'Sent back to the requester for more information',
|
|
3413
4095
|
remindBtn: 'Send reminder',
|
|
3414
4096
|
remindSuccess: 'Reminder sent to {{count}} approver(s)',
|
|
4097
|
+
remindSuccess_one: 'Reminder sent to {{count}} approver',
|
|
4098
|
+
remindSuccess_other: 'Reminder sent to {{count}} approvers',
|
|
3415
4099
|
remindThrottled: 'A reminder was sent recently — try again later.',
|
|
3416
4100
|
replyPlaceholder: 'Reply on this request…',
|
|
3417
4101
|
slaRemaining: 'SLA {{dur}} left',
|
|
@@ -3428,6 +4112,8 @@ const en = {
|
|
|
3428
4112
|
progressApprovals: 'Approvals — {{got}} of {{need}}',
|
|
3429
4113
|
progressGroups: 'Sign-off progress — {{got}} of {{need}} groups',
|
|
3430
4114
|
progressEligible: '{{count}} eligible approver(s)',
|
|
4115
|
+
progressEligible_one: '{{count}} eligible approver',
|
|
4116
|
+
progressEligible_other: '{{count}} eligible approvers',
|
|
3431
4117
|
progressBar: 'Decision progress',
|
|
3432
4118
|
declaredActions: 'Actions',
|
|
3433
4119
|
attachmentChip: 'Attachment',
|
|
@@ -3459,6 +4145,8 @@ const en = {
|
|
|
3459
4145
|
filterCount: '{{shown}} of {{total}}',
|
|
3460
4146
|
selected: 'selected',
|
|
3461
4147
|
actionableCount: '({{count}} actionable)',
|
|
4148
|
+
actionableCount_one: '({{count}} actionable)',
|
|
4149
|
+
actionableCount_other: '({{count}} actionable)',
|
|
3462
4150
|
selectAll: 'Select all',
|
|
3463
4151
|
selectRow: 'Select request',
|
|
3464
4152
|
colRequest: 'Request',
|
|
@@ -3499,12 +4187,19 @@ const en = {
|
|
|
3499
4187
|
submittedAgo: 'Submitted {{when}}',
|
|
3500
4188
|
completedAt: 'Completed {{when}}',
|
|
3501
4189
|
waitingOn: 'Waiting on',
|
|
4190
|
+
approverNameSeparator: ', ',
|
|
4191
|
+
approverUnstaffed: '{{seat}} (no current holder)',
|
|
3502
4192
|
history: 'Activity',
|
|
3503
4193
|
noActions: 'No actions yet.',
|
|
3504
4194
|
actSubmit: 'Submitted',
|
|
3505
4195
|
actApprove: 'Approved',
|
|
3506
4196
|
actReject: 'Rejected',
|
|
3507
4197
|
actRecall: 'Recalled',
|
|
4198
|
+
overrideActionLabel: 'Override {{action}}',
|
|
4199
|
+
overrideNotice: 'You hold no approver slot on this step. Continuing uses your admin override: it finalises the step immediately, bypassing any approver who has not acted. The decision is recorded as an admin override.',
|
|
4200
|
+
overrideNoticeWho: 'You hold no approver slot on this step. Continuing uses your admin override: it finalises the step immediately and bypasses the approvers who have not acted — {{who}}. The decision is recorded as an admin override.',
|
|
4201
|
+
viaOverrideChip: 'Admin override',
|
|
4202
|
+
viaOverrideHint: 'The actor held no approver slot on this step — admitted by the admin-override path.',
|
|
3508
4203
|
rawData: 'Raw data (JSON)',
|
|
3509
4204
|
copy: 'Copy',
|
|
3510
4205
|
copied: 'Copied',
|
|
@@ -3525,11 +4220,19 @@ const en = {
|
|
|
3525
4220
|
approveN: 'Approve {{count}}',
|
|
3526
4221
|
rejectN: 'Reject {{count}}',
|
|
3527
4222
|
bulkApproveTitle: 'Approve {{count}} requests?',
|
|
4223
|
+
bulkApproveTitle_one: 'Approve {{count}} request?',
|
|
4224
|
+
bulkApproveTitle_other: 'Approve {{count}} requests?',
|
|
3528
4225
|
bulkApproveBody: 'Each request is approved with your identity and its flow continues down the approve branch.',
|
|
3529
4226
|
bulkRejectTitle: 'Reject {{count}} requests?',
|
|
4227
|
+
bulkRejectTitle_one: 'Reject {{count}} request?',
|
|
4228
|
+
bulkRejectTitle_other: 'Reject {{count}} requests?',
|
|
3530
4229
|
bulkRejectBody: 'This rejects the selected requests and notifies their submitters.',
|
|
3531
4230
|
bulkApproved: 'Approved {{count}} requests',
|
|
4231
|
+
bulkApproved_one: 'Approved {{count}} request',
|
|
4232
|
+
bulkApproved_other: 'Approved {{count}} requests',
|
|
3532
4233
|
bulkRejected: 'Rejected {{count}} requests',
|
|
4234
|
+
bulkRejected_one: 'Rejected {{count}} request',
|
|
4235
|
+
bulkRejected_other: 'Rejected {{count}} requests',
|
|
3533
4236
|
bulkPartial: '{{ok}} succeeded, {{fail}} failed: {{which}}',
|
|
3534
4237
|
rejectOneTitle: 'Reject "{{title}}"?',
|
|
3535
4238
|
rejectOneBody: 'This rejects the request and notifies the submitter.',
|
|
@@ -3554,8 +4257,14 @@ const en = {
|
|
|
3554
4257
|
alreadyDecided: 'This request was already decided. Refresh the list.',
|
|
3555
4258
|
justNow: 'just now',
|
|
3556
4259
|
minutesAgo: '{{count}}m ago',
|
|
4260
|
+
minutesAgo_one: '{{count}}m ago',
|
|
4261
|
+
minutesAgo_other: '{{count}}m ago',
|
|
3557
4262
|
hoursAgo: '{{count}}h ago',
|
|
4263
|
+
hoursAgo_one: '{{count}}h ago',
|
|
4264
|
+
hoursAgo_other: '{{count}}h ago',
|
|
3558
4265
|
daysAgo: '{{count}}d ago',
|
|
4266
|
+
daysAgo_one: '{{count}}d ago',
|
|
4267
|
+
daysAgo_other: '{{count}}d ago',
|
|
3559
4268
|
},
|
|
3560
4269
|
filterBuilder: {
|
|
3561
4270
|
where: 'Where',
|
|
@@ -3573,22 +4282,33 @@ const en = {
|
|
|
3573
4282
|
noResults: 'No results',
|
|
3574
4283
|
searchField: 'Search {{label}}…',
|
|
3575
4284
|
enterId: 'Enter {{label}} id',
|
|
4285
|
+
addValue: 'Type a value, press Enter',
|
|
4286
|
+
removeValue: 'Remove {{value}}',
|
|
4287
|
+
rangeStart: 'From',
|
|
4288
|
+
rangeEnd: 'To',
|
|
3576
4289
|
operators: {
|
|
3577
4290
|
equals: 'Equals',
|
|
3578
|
-
|
|
4291
|
+
not_equals: 'Does not equal',
|
|
3579
4292
|
contains: 'Contains',
|
|
3580
|
-
|
|
3581
|
-
|
|
3582
|
-
|
|
3583
|
-
|
|
3584
|
-
|
|
3585
|
-
|
|
3586
|
-
|
|
4293
|
+
icontains: 'Contains (ignore case)',
|
|
4294
|
+
not_contains: 'Does not contain',
|
|
4295
|
+
is_empty: 'Is empty',
|
|
4296
|
+
is_not_empty: 'Is not empty',
|
|
4297
|
+
greater_than: 'Greater than',
|
|
4298
|
+
less_than: 'Less than',
|
|
4299
|
+
greater_than_or_equal: 'Greater than or equal',
|
|
4300
|
+
less_than_or_equal: 'Less than or equal',
|
|
3587
4301
|
before: 'Before',
|
|
3588
4302
|
after: 'After',
|
|
3589
4303
|
between: 'Between',
|
|
3590
4304
|
in: 'In',
|
|
3591
|
-
|
|
4305
|
+
not_in: 'Not in',
|
|
4306
|
+
starts_with: 'Starts with',
|
|
4307
|
+
ends_with: 'Ends with',
|
|
4308
|
+
is_null: 'Is null',
|
|
4309
|
+
is_not_null: 'Is not null',
|
|
4310
|
+
exists: 'Is set',
|
|
4311
|
+
notExists: 'Is not set',
|
|
3592
4312
|
},
|
|
3593
4313
|
},
|
|
3594
4314
|
sortBuilder: {
|
|
@@ -3609,13 +4329,11 @@ const en = {
|
|
|
3609
4329
|
// The generic action words (Save / Cancel / Edit / Delete) are NOT repeated
|
|
3610
4330
|
// here — the thread reads them from `common`.
|
|
3611
4331
|
collaboration: {
|
|
3612
|
-
// Thread header.
|
|
3613
|
-
//
|
|
3614
|
-
// `detail`: zh/ja/ko have no separate singular form, so those packs would
|
|
3615
|
-
// legitimately omit the `_one` half and `all-locales-key-parity` reads a
|
|
3616
|
-
// legitimately-absent half as a lost key.
|
|
4332
|
+
// Thread header. An i18next count family (objectui#11445): the component
|
|
4333
|
+
// passes `count` and i18next picks the slot each pack's CLDR rules select.
|
|
3617
4334
|
commentCount: '{{count}} comments',
|
|
3618
|
-
|
|
4335
|
+
commentCount_one: '{{count}} comment',
|
|
4336
|
+
commentCount_other: '{{count}} comments',
|
|
3619
4337
|
// Appended to the count, separator included, so a translator owns the
|
|
3620
4338
|
// whole phrase rather than inheriting an English-shaped ` · ` glue.
|
|
3621
4339
|
resolvedSuffix: ' · Resolved',
|
|
@@ -3628,14 +4346,21 @@ const en = {
|
|
|
3628
4346
|
// existing minute/hour/day buckets and no date library was introduced.
|
|
3629
4347
|
justNow: 'just now',
|
|
3630
4348
|
minutesAgo: '{{count}}m ago',
|
|
4349
|
+
minutesAgo_one: '{{count}}m ago',
|
|
4350
|
+
minutesAgo_other: '{{count}}m ago',
|
|
3631
4351
|
hoursAgo: '{{count}}h ago',
|
|
4352
|
+
hoursAgo_one: '{{count}}h ago',
|
|
4353
|
+
hoursAgo_other: '{{count}}h ago',
|
|
3632
4354
|
daysAgo: '{{count}}d ago',
|
|
4355
|
+
daysAgo_one: '{{count}}d ago',
|
|
4356
|
+
daysAgo_other: '{{count}}d ago',
|
|
3633
4357
|
edited: '(edited)',
|
|
3634
4358
|
// Reaction-chip tooltip. A DEDICATED pair rather than `detail.reactionCount`:
|
|
3635
4359
|
// that one interpolates `{{emoji}}`, and here the emoji is the chip's
|
|
3636
4360
|
// visible label with nothing to hand the placeholder.
|
|
3637
4361
|
reactionCount: '{{count}} reactions',
|
|
3638
|
-
|
|
4362
|
+
reactionCount_one: '{{count}} reaction',
|
|
4363
|
+
reactionCount_other: '{{count}} reactions',
|
|
3639
4364
|
addThumbsUp: 'Add thumbs up',
|
|
3640
4365
|
reply: 'Reply',
|
|
3641
4366
|
// Accessible names for the three emoji-only controls (objectui#3441).
|
|
@@ -3661,12 +4386,14 @@ const en = {
|
|
|
3661
4386
|
send: 'Send',
|
|
3662
4387
|
// Presence avatar stack (objectui#3440). `presentUserCount*` is the avatar
|
|
3663
4388
|
// group's `aria-label` — with only images and initials inside, that label
|
|
3664
|
-
// IS the control for a screen reader.
|
|
3665
|
-
//
|
|
4389
|
+
// IS the control for a screen reader. Count families, like `commentCount`
|
|
4390
|
+
// above.
|
|
3666
4391
|
presentUserCount: '{{count}} users present',
|
|
3667
|
-
|
|
4392
|
+
presentUserCount_one: '{{count}} user present',
|
|
4393
|
+
presentUserCount_other: '{{count}} users present',
|
|
3668
4394
|
moreUserCount: '{{count}} more users',
|
|
3669
|
-
|
|
4395
|
+
moreUserCount_one: '{{count}} more user',
|
|
4396
|
+
moreUserCount_other: '{{count}} more users',
|
|
3670
4397
|
// Avatar tooltip. The parentheses are part of the translation, spacing
|
|
3671
4398
|
// included, so the CJK packs can drop the space English puts before `(`.
|
|
3672
4399
|
userStatusTitle: '{{name}} ({{status}})',
|
|
@@ -3681,6 +4408,49 @@ const en = {
|
|
|
3681
4408
|
// comma-joined, already-truncated label list built at the call site.
|
|
3682
4409
|
wizard: {
|
|
3683
4410
|
missingRequired: 'Please complete the required fields: {{fields}}',
|
|
4411
|
+
// The wizard's footer and step chrome (objectui#10999). The generic verbs
|
|
4412
|
+
// it shows come from `common.cancel`, `common.next`, `form.create`,
|
|
4413
|
+
// `form.update` and `form.stepOf`; these five are the wizard's own.
|
|
4414
|
+
// The Previous-step button. Not `common.back`: some packs say a wizard's
|
|
4415
|
+
// step back with a different word from a page's back (zh reads "previous
|
|
4416
|
+
// step" here and "return" for `common.back`), and the wizard spelling is
|
|
4417
|
+
// the one `grid.import.back` and `grid.bulk.back` already use.
|
|
4418
|
+
back: 'Back',
|
|
4419
|
+
// The final button while the record is being written.
|
|
4420
|
+
submitting: 'Submitting…',
|
|
4421
|
+
// The step indicator's label for a step that declares no `label`.
|
|
4422
|
+
// `{{n}}` is the 1-based step number.
|
|
4423
|
+
stepFallback: 'Step {{n}}',
|
|
4424
|
+
// The step indicator's `aria-label` — what a screen reader calls the list
|
|
4425
|
+
// of steps.
|
|
4426
|
+
progressLabel: 'Progress',
|
|
4427
|
+
// Shown in place of the fields on a step that has none (a final review
|
|
4428
|
+
// step is the usual case).
|
|
4429
|
+
emptyStep: 'No fields configured for this step',
|
|
4430
|
+
},
|
|
4431
|
+
// The screen-flow runner dialog (`app-shell/views/FlowRunner`) — the modal a
|
|
4432
|
+
// `type: 'flow'` action opens when its run pauses at a `screen` node.
|
|
4433
|
+
//
|
|
4434
|
+
// What is deliberately NOT here: the sentence a refused resume shows. That is
|
|
4435
|
+
// the ADR-0112 envelope's own `error.message`, prose the automation engine
|
|
4436
|
+
// composed for a human ("Node 'create_quote' failed: … at most 2 decimal
|
|
4437
|
+
// places"), so it has no fixed catalogue to key against and is passed through
|
|
4438
|
+
// untranslated — the same division `appManagement` states above. The runner
|
|
4439
|
+
// borrows `common.{loading,cancel,close,submit}` for its chrome and
|
|
4440
|
+
// `wizard.missingRequired` for the pre-submit check, which is the same
|
|
4441
|
+
// sentence `plugin-form`'s WizardForm raises.
|
|
4442
|
+
flowRunner: {
|
|
4443
|
+
// Fallback dialog title, used only when the `screen` node declares none.
|
|
4444
|
+
title: 'Input',
|
|
4445
|
+
submitting: 'Submitting…',
|
|
4446
|
+
// The submit label of an `object-form` step: it saves a record AND advances
|
|
4447
|
+
// the run, so it is not the plain `common.submit`.
|
|
4448
|
+
saveAndContinue: 'Save & Continue',
|
|
4449
|
+
// A multi-screen wizard advanced to the next step (not the end of the run).
|
|
4450
|
+
nextStep: 'Saved — next step',
|
|
4451
|
+
// Terminal success, used only when the flow declares no `successMessage`
|
|
4452
|
+
// of its own.
|
|
4453
|
+
completed: 'Flow "{{flow}}" completed',
|
|
3684
4454
|
},
|
|
3685
4455
|
// Console › System › Applications (objectui#4307). The page's OWN chrome —
|
|
3686
4456
|
// headings, controls, badges and the frames of its toasts.
|
|
@@ -3760,5 +4530,77 @@ const en = {
|
|
|
3760
4530
|
bulkOperationFailed: 'Bulk operation failed: {{reason}}',
|
|
3761
4531
|
},
|
|
3762
4532
|
},
|
|
4533
|
+
// objectui#6301 — Setup › Packaged automation (ADR-0126 §7.4): the
|
|
4534
|
+
// operational surface for the flows an installed package ships. Authoring
|
|
4535
|
+
// stays in Studio, so this group has no editing vocabulary at all; it is
|
|
4536
|
+
// on/off, clone, and the states those two produce.
|
|
4537
|
+
//
|
|
4538
|
+
// ⛔ No drift or ancestry wording anywhere in this group (ADR-0126 §9). There
|
|
4539
|
+
// is deliberately no "customized", no "based on v3", no "out of date" — the
|
|
4540
|
+
// platform does not track that lineage, and a translatable string for it is
|
|
4541
|
+
// the cheapest way for the surface to grow one.
|
|
4542
|
+
//
|
|
4543
|
+
// ⛔ Server refusals are NOT in this group either. The posture gate, the
|
|
4544
|
+
// subflow guard and the clone name conflict all arrive as server-authored
|
|
4545
|
+
// prose and are rendered verbatim; the four `*Failed*` keys below are the
|
|
4546
|
+
// last-resort fallbacks for a response that carried no message at all.
|
|
4547
|
+
packagedAutomation: {
|
|
4548
|
+
title: 'Packaged automation',
|
|
4549
|
+
// Covers BOTH sections since ADR-0126 §8 item 2 put packaged actions on
|
|
4550
|
+
// this page: only flows can be cloned, so the clone clause names them.
|
|
4551
|
+
subtitle: 'Flows and actions shipped by installed packages. Turn one off for this deployment, or clone a flow under a new name to customize it. Editing happens in Studio.',
|
|
4552
|
+
refresh: 'Refresh',
|
|
4553
|
+
// Section headings — the page carries two tables.
|
|
4554
|
+
flowsHeading: 'Packaged flows',
|
|
4555
|
+
actionsHeading: 'Packaged actions',
|
|
4556
|
+
colFlow: 'Flow',
|
|
4557
|
+
colActivation: 'Activation',
|
|
4558
|
+
colActions: 'Actions',
|
|
4559
|
+
// The switch's accessible name — the only place a row's label is spoken.
|
|
4560
|
+
toggleLabel: 'Activation for {{label}}',
|
|
4561
|
+
on: 'On',
|
|
4562
|
+
off: 'Off',
|
|
4563
|
+
clone: 'Clone',
|
|
4564
|
+
cloneTitle: 'Clone packaged flow',
|
|
4565
|
+
cloneBody: 'The copy carries the whole definition and takes a new machine name and label. Edit the copy in Studio.',
|
|
4566
|
+
cloneName: 'New machine name',
|
|
4567
|
+
cloneLabel: 'New label',
|
|
4568
|
+
cancel: 'Cancel',
|
|
4569
|
+
cloneConfirm: 'Create clone',
|
|
4570
|
+
cloneCreated: 'Created flow "{{name}}".',
|
|
4571
|
+
emptyTitle: 'No packaged flows',
|
|
4572
|
+
emptyBody: 'No installed package ships an automation flow on this deployment. Flows you author yourself live in Studio.',
|
|
4573
|
+
loadFailed: 'Could not load packaged automation.',
|
|
4574
|
+
// Two keys per action, not one: the response arm has an HTTP status to
|
|
4575
|
+
// name and the transport-exception arm does not, and a single key cannot
|
|
4576
|
+
// carry a hole only half its call sites can fill.
|
|
4577
|
+
// Artifact-neutral by wording, and shared by BOTH sections' toggles: the
|
|
4578
|
+
// sentence says nothing about flows, so the actions half reuses it rather
|
|
4579
|
+
// than defining a second key with the same English in ten packs.
|
|
4580
|
+
toggleFailedHttp: 'Could not change activation (HTTP {{status}}).',
|
|
4581
|
+
toggleFailed: 'Could not change activation.',
|
|
4582
|
+
cloneFailedHttp: 'Could not clone this flow (HTTP {{status}}).',
|
|
4583
|
+
cloneFailed: 'Could not clone this flow.',
|
|
4584
|
+
// ── Packaged ACTIONS section (ADR-0126 §8 item 2, ruling 3) ────────────
|
|
4585
|
+
// ⛔ No clone key here on purpose: the action-clone half is unchartered,
|
|
4586
|
+
// and a string is the cheapest way for an unchartered surface to appear.
|
|
4587
|
+
actionsSubtitle: 'Actions shipped by installed packages. Turn one off for this deployment and it stops running everywhere it is offered. Authoring your own action alongside it stays open in Studio.',
|
|
4588
|
+
colAction: 'Action',
|
|
4589
|
+
colObject: 'Object',
|
|
4590
|
+
// The object is part of the accessible name because it is part of the
|
|
4591
|
+
// identity — two objects may declare the same action name.
|
|
4592
|
+
actionToggleLabel: 'Activation for {{label}} on {{object}}',
|
|
4593
|
+
actionsEmptyTitle: 'No packaged actions',
|
|
4594
|
+
actionsEmptyBody: 'No installed package declares an action on this deployment. Actions you author yourself live in Studio.',
|
|
4595
|
+
actionsLoadFailed: 'Could not load packaged actions.',
|
|
4596
|
+
},
|
|
4597
|
+
element: {
|
|
4598
|
+
// objectui#10951 — `element:number` authored with an aggregate and no
|
|
4599
|
+
// object (neither `object` nor `dataSource.object`). Kept terse: this pack
|
|
4600
|
+
// is eager, and the console closure budget weighs it.
|
|
4601
|
+
number: {
|
|
4602
|
+
noObject: 'No object named: set object or dataSource.object.',
|
|
4603
|
+
},
|
|
4604
|
+
},
|
|
3763
4605
|
};
|
|
3764
4606
|
export default en;
|