@object-ui/i18n 3.0.3 → 3.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. package/.turbo/turbo-build.log +1 -1
  2. package/dist/index.d.ts +1 -0
  3. package/dist/index.js +2 -0
  4. package/dist/locales/ar.d.ts +314 -0
  5. package/dist/locales/ar.js +314 -0
  6. package/dist/locales/de.d.ts +314 -0
  7. package/dist/locales/de.js +314 -0
  8. package/dist/locales/en.d.ts +372 -0
  9. package/dist/locales/en.js +372 -0
  10. package/dist/locales/es.d.ts +314 -0
  11. package/dist/locales/es.js +314 -0
  12. package/dist/locales/fr.d.ts +314 -0
  13. package/dist/locales/fr.js +314 -0
  14. package/dist/locales/index.d.ts +3256 -0
  15. package/dist/locales/ja.d.ts +314 -0
  16. package/dist/locales/ja.js +314 -0
  17. package/dist/locales/ko.d.ts +314 -0
  18. package/dist/locales/ko.js +314 -0
  19. package/dist/locales/pt.d.ts +314 -0
  20. package/dist/locales/pt.js +314 -0
  21. package/dist/locales/ru.d.ts +314 -0
  22. package/dist/locales/ru.js +314 -0
  23. package/dist/locales/zh.d.ts +372 -0
  24. package/dist/locales/zh.js +372 -0
  25. package/dist/provider.js +34 -4
  26. package/dist/useObjectLabel.d.ts +61 -0
  27. package/dist/useObjectLabel.js +114 -0
  28. package/package.json +3 -3
  29. package/src/__tests__/useObjectLabel.test.tsx +131 -0
  30. package/src/index.ts +3 -0
  31. package/src/locales/ar.ts +314 -0
  32. package/src/locales/de.ts +314 -0
  33. package/src/locales/en.ts +372 -0
  34. package/src/locales/es.ts +314 -0
  35. package/src/locales/fr.ts +314 -0
  36. package/src/locales/ja.ts +314 -0
  37. package/src/locales/ko.ts +314 -0
  38. package/src/locales/pt.ts +314 -0
  39. package/src/locales/ru.ts +314 -0
  40. package/src/locales/zh.ts +372 -0
  41. package/src/provider.tsx +33 -4
  42. package/src/useObjectLabel.ts +122 -0
  43. package/tsconfig.tsbuildinfo +1 -1
@@ -0,0 +1,131 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import { renderHook } from '@testing-library/react';
3
+ import React from 'react';
4
+ import { I18nProvider } from '../provider';
5
+ import { createI18n } from '../i18n';
6
+ import { useObjectLabel } from '../useObjectLabel';
7
+
8
+ /**
9
+ * Create a wrapper with custom translations to simulate CRM locale bundles.
10
+ */
11
+ function createWrapper(lang: string, translations?: Record<string, unknown>) {
12
+ const instance = createI18n({ defaultLanguage: lang, detectBrowserLanguage: false });
13
+ if (translations) {
14
+ instance.addResourceBundle(lang, 'translation', translations, true, true);
15
+ }
16
+ return ({ children }: { children: React.ReactNode }) =>
17
+ React.createElement(I18nProvider, { instance }, children);
18
+ }
19
+
20
+ describe('useObjectLabel', () => {
21
+ describe('objectLabel', () => {
22
+ it('returns the plain label when no translation exists', () => {
23
+ const wrapper = createWrapper('en');
24
+ const { result } = renderHook(() => useObjectLabel(), { wrapper });
25
+
26
+ const label = result.current.objectLabel({ name: 'order_item', label: 'Order Item' });
27
+ expect(label).toBe('Order Item');
28
+ });
29
+
30
+ it('returns the translated label when a translation exists', () => {
31
+ const wrapper = createWrapper('zh', {
32
+ crm: { objects: { order_item: { label: '订单明细' } } },
33
+ });
34
+ const { result } = renderHook(() => useObjectLabel(), { wrapper });
35
+
36
+ const label = result.current.objectLabel({ name: 'order_item', label: 'Order Item' });
37
+ expect(label).toBe('订单明细');
38
+ });
39
+
40
+ it('falls back to plain label when translation key returns empty string', () => {
41
+ const wrapper = createWrapper('zh', {
42
+ crm: { objects: { order_item: { label: '' } } },
43
+ });
44
+ const { result } = renderHook(() => useObjectLabel(), { wrapper });
45
+
46
+ const label = result.current.objectLabel({ name: 'order_item', label: 'Order Item' });
47
+ expect(label).toBe('Order Item');
48
+ });
49
+ });
50
+
51
+ describe('objectDescription', () => {
52
+ it('returns undefined when objectDef has no description', () => {
53
+ const wrapper = createWrapper('en');
54
+ const { result } = renderHook(() => useObjectLabel(), { wrapper });
55
+
56
+ const desc = result.current.objectDescription({ name: 'order_item' });
57
+ expect(desc).toBeUndefined();
58
+ });
59
+
60
+ it('returns the plain description when no translation exists', () => {
61
+ const wrapper = createWrapper('en');
62
+ const { result } = renderHook(() => useObjectLabel(), { wrapper });
63
+
64
+ const desc = result.current.objectDescription({ name: 'order_item', description: 'Line items in an order' });
65
+ expect(desc).toBe('Line items in an order');
66
+ });
67
+
68
+ it('returns the translated description when a translation exists', () => {
69
+ const wrapper = createWrapper('zh', {
70
+ crm: { objects: { order_item: { description: '订单中的商品条目' } } },
71
+ });
72
+ const { result } = renderHook(() => useObjectLabel(), { wrapper });
73
+
74
+ const desc = result.current.objectDescription({ name: 'order_item', description: 'Line items in an order' });
75
+ expect(desc).toBe('订单中的商品条目');
76
+ });
77
+ });
78
+
79
+ describe('fieldLabel', () => {
80
+ it('returns the fallback label when no translation exists', () => {
81
+ const wrapper = createWrapper('en');
82
+ const { result } = renderHook(() => useObjectLabel(), { wrapper });
83
+
84
+ const label = result.current.fieldLabel('order_item', 'name', 'Line Item');
85
+ expect(label).toBe('Line Item');
86
+ });
87
+
88
+ it('returns the translated label when a translation exists', () => {
89
+ const wrapper = createWrapper('zh', {
90
+ crm: { fields: { order_item: { name: '订单项' } } },
91
+ });
92
+ const { result } = renderHook(() => useObjectLabel(), { wrapper });
93
+
94
+ const label = result.current.fieldLabel('order_item', 'name', 'Line Item');
95
+ expect(label).toBe('订单项');
96
+ });
97
+
98
+ it('falls back to plain label when translation key returns empty string', () => {
99
+ const wrapper = createWrapper('zh', {
100
+ crm: { fields: { order_item: { name: '' } } },
101
+ });
102
+ const { result } = renderHook(() => useObjectLabel(), { wrapper });
103
+
104
+ const label = result.current.fieldLabel('order_item', 'name', 'Line Item');
105
+ expect(label).toBe('Line Item');
106
+ });
107
+ });
108
+
109
+ describe('multiple objects', () => {
110
+ it('resolves labels for different objects independently', () => {
111
+ const wrapper = createWrapper('zh', {
112
+ crm: {
113
+ objects: {
114
+ contact: { label: '联系人' },
115
+ opportunity: { label: '商机' },
116
+ },
117
+ fields: {
118
+ contact: { email: '邮箱' },
119
+ opportunity: { stage: '阶段' },
120
+ },
121
+ },
122
+ });
123
+ const { result } = renderHook(() => useObjectLabel(), { wrapper });
124
+
125
+ expect(result.current.objectLabel({ name: 'contact', label: 'Contact' })).toBe('联系人');
126
+ expect(result.current.objectLabel({ name: 'opportunity', label: 'Opportunity' })).toBe('商机');
127
+ expect(result.current.fieldLabel('contact', 'email', 'Email')).toBe('邮箱');
128
+ expect(result.current.fieldLabel('opportunity', 'stage', 'Stage')).toBe('阶段');
129
+ });
130
+ });
131
+ });
package/src/index.ts CHANGED
@@ -37,6 +37,9 @@ export { createI18n, getDirection, getAvailableLanguages, type I18nConfig, type
37
37
  // React integration
38
38
  export { I18nProvider, useObjectTranslation, useI18nContext, type I18nProviderProps } from './provider';
39
39
 
40
+ // Convention-based object/field label i18n
41
+ export { useObjectLabel, useSafeFieldLabel } from './useObjectLabel';
42
+
40
43
  // Locale packs
41
44
  export { builtInLocales, isRTL, RTL_LANGUAGES } from './locales/index';
42
45
  export { default as en } from './locales/en';
package/src/locales/ar.ts CHANGED
@@ -70,6 +70,24 @@ const ar = {
70
70
  selectAllRows: 'تحديد جميع الصفوف',
71
71
  expandRow: 'توسيع الصف',
72
72
  collapseRow: 'طي الصف',
73
+ hideColumn: 'إخفاء العمود',
74
+ freezeColumn: 'تجميد العمود',
75
+ unfreezeColumn: 'إلغاء تجميد العمود',
76
+ pageInfo: 'صفحة {{current}} من {{total}}',
77
+ totalRecords: '{{count}} إجمالي',
78
+ },
79
+ grid: {
80
+ actions: 'إجراءات',
81
+ edit: 'تعديل',
82
+ delete: 'حذف',
83
+ export: 'تصدير',
84
+ exportAs: 'تصدير كـ {{format}}',
85
+ loading: 'جاري تحميل الشبكة...',
86
+ errorLoading: 'خطأ في تحميل الشبكة',
87
+ pullToRefresh: 'اسحب للتحديث',
88
+ refreshing: 'جاري التحديث…',
89
+ openRecord: 'فتح السجل',
90
+ rowHeight: 'ارتفاع الصف: {{mode}}',
73
91
  },
74
92
  calendar: {
75
93
  today: 'اليوم',
@@ -80,6 +98,31 @@ const ar = {
80
98
  allDay: 'طوال اليوم',
81
99
  noEvents: 'لا توجد أحداث',
82
100
  newEvent: 'حدث جديد',
101
+ moreEvents: '+{{count}} المزيد',
102
+ },
103
+ list: {
104
+ recordCount: '{{count}} سجلات',
105
+ recordCountOne: '{{count}} سجل',
106
+ addRecord: 'إضافة سجل',
107
+ tabs: 'علامات التبويب',
108
+ allRecords: 'جميع السجلات',
109
+ search: 'بحث',
110
+ filter: 'تصفية',
111
+ filterRecords: 'تصفية السجلات',
112
+ sort: 'ترتيب',
113
+ sortRecords: 'ترتيب السجلات',
114
+ group: 'تجميع',
115
+ groupBy: 'تجميع حسب',
116
+ export: 'تصدير',
117
+ exportAs: 'تصدير كـ {{format}}',
118
+ color: 'لون',
119
+ rowColor: 'لون الصف',
120
+ colorByField: 'تلوين حسب الحقل',
121
+ clear: 'مسح',
122
+ none: 'لا شيء',
123
+ hideFields: 'إخفاء الحقول',
124
+ noItems: 'لم يتم العثور على عناصر',
125
+ noItemsMessage: 'لا توجد سجلات للعرض. حاول تعديل الفلاتر أو إضافة بيانات جديدة.',
83
126
  },
84
127
  kanban: {
85
128
  addCard: 'إضافة بطاقة',
@@ -88,6 +131,41 @@ const ar = {
88
131
  deleteCard: 'حذف بطاقة',
89
132
  deleteColumn: 'حذف عمود',
90
133
  },
134
+ detail: {
135
+ back: 'رجوع',
136
+ edit: 'تحرير',
137
+ editInline: 'تحرير مباشر',
138
+ save: 'حفظ',
139
+ saveChanges: 'حفظ التغييرات',
140
+ editFieldsInline: 'تحرير الحقول مباشرة',
141
+ share: 'مشاركة',
142
+ duplicate: 'نسخ',
143
+ export: 'تصدير',
144
+ viewHistory: 'عرض السجل',
145
+ delete: 'حذف',
146
+ moreActions: 'المزيد من الإجراءات',
147
+ addToFavorites: 'إضافة إلى المفضلة',
148
+ removeFromFavorites: 'إزالة من المفضلة',
149
+ previousRecord: 'السجل السابق',
150
+ nextRecord: 'السجل التالي',
151
+ recordOf: '{{current}} من {{total}}',
152
+ recordNotFound: 'لم يتم العثور على السجل',
153
+ recordNotFoundDescription: 'السجل الذي تبحث عنه غير موجود أو ربما تم حذفه.',
154
+ goBack: 'رجوع',
155
+ details: 'التفاصيل',
156
+ related: 'ذات صلة',
157
+ relatedRecords: '{{count}} سجلات',
158
+ relatedRecordOne: '{{count}} سجل',
159
+ noRelatedRecords: 'لا توجد سجلات ذات صلة',
160
+ loading: 'جاري التحميل...',
161
+ copyToClipboard: 'نسخ إلى الحافظة',
162
+ copied: 'تم النسخ!',
163
+ deleteConfirmation: 'هل أنت متأكد أنك تريد حذف هذا السجل؟',
164
+ editRecord: 'تحرير السجل',
165
+ viewAll: 'عرض الكل',
166
+ new: 'جديد',
167
+ emptyValue: '—',
168
+ },
91
169
  chart: {
92
170
  noData: 'لا تتوفر بيانات للرسم البياني',
93
171
  loading: 'جاري تحميل الرسم البياني...',
@@ -99,9 +177,162 @@ const ar = {
99
177
  saveLayout: 'حفظ التخطيط',
100
178
  resetLayout: 'إعادة تعيين التخطيط',
101
179
  },
180
+ configPanel: {
181
+ save: 'حفظ',
182
+ discard: 'تجاهل',
183
+ close: 'إغلاق',
184
+ layout: 'التخطيط',
185
+ columns: 'الأعمدة',
186
+ gap: 'المسافة',
187
+ rowHeight: 'ارتفاع الصف',
188
+ data: 'البيانات',
189
+ refreshInterval: 'فترة التحديث',
190
+ appearance: 'المظهر',
191
+ title: 'العنوان',
192
+ showDescription: 'إظهار الوصف',
193
+ theme: 'السمة',
194
+ configuration: 'الإعداد',
195
+ general: 'عام',
196
+ advanced: 'متقدم',
197
+ },
198
+ appDesigner: {
199
+ createApp: 'Create Application',
200
+ editApp: 'Edit Application',
201
+ basicInfo: 'Basic Info',
202
+ objects: 'Objects',
203
+ navigation: 'Navigation',
204
+ branding: 'Branding',
205
+ appName: 'App Name',
206
+ appTitle: 'Title',
207
+ appDescription: 'Description',
208
+ appIcon: 'Icon',
209
+ template: 'Template',
210
+ layout: 'Layout',
211
+ layoutSidebar: 'Sidebar',
212
+ layoutHeader: 'Header',
213
+ layoutEmpty: 'Empty',
214
+ selectObjects: 'Select Objects',
215
+ searchObjects: 'Search objects…',
216
+ selectAll: 'Select All',
217
+ deselectAll: 'Deselect All',
218
+ navBuilder: 'Navigation Builder',
219
+ addGroup: 'Add Group',
220
+ addUrl: 'Add URL',
221
+ addSeparator: 'Add Separator',
222
+ noNavItems: 'No navigation items yet.',
223
+ logoUrl: 'Logo URL',
224
+ primaryColor: 'Primary Color',
225
+ faviconUrl: 'Favicon URL',
226
+ preview: 'Preview',
227
+ complete: 'Complete',
228
+ snakeCaseHint: 'Must be snake_case (e.g. my_app)',
229
+ modeEdit: 'Edit',
230
+ modePreview: 'Preview',
231
+ modeCode: 'Code',
232
+ addWidget: 'Add Widget',
233
+ widgetProperties: 'Widget Properties',
234
+ dataSource: 'Data Source',
235
+ valueField: 'Value Field',
236
+ aggregate: 'Aggregate',
237
+ colorVariant: 'Color Variant',
238
+ addComponent: 'Add Component',
239
+ componentProperties: 'Component Properties',
240
+ viewType: 'View Type',
241
+ fields: 'Fields',
242
+ toolbar: 'Toolbar',
243
+ showSearch: 'Show Search',
244
+ showFilters: 'Show Filters',
245
+ showSort: 'Show Sort',
246
+ appearance: 'Appearance',
247
+ rowHeight: 'Row Height',
248
+ stripedRows: 'Striped Rows',
249
+ bordered: 'Bordered',
250
+ livePreview: 'Live Preview',
251
+ stepBasicDesc: 'الاسم والعنوان والتخطيط',
252
+ stepObjectsDesc: 'اختيار كائنات الأعمال',
253
+ stepNavigationDesc: 'بناء شجرة التنقل',
254
+ stepBrandingDesc: 'الشعار والألوان والأيقونة',
255
+ noObjectsFound: 'لم يتم العثور على كائنات.',
256
+ noNavItemsHint: 'لا توجد عناصر تنقل بعد. حدد كائنات في الخطوة السابقة أو أضف عناصر يدويًا.',
257
+ separator: 'فاصل',
258
+ separatorLabel: '— فاصل —',
259
+ newGroup: 'مجموعة جديدة',
260
+ newLink: 'رابط جديد',
261
+ saveDraft: 'حفظ المسودة',
262
+ cancelConfirmTitle: 'تجاهل التغييرات؟',
263
+ cancelConfirmMessage: 'لديك تغييرات غير محفوظة. هل أنت متأكد من الإلغاء؟',
264
+ confirmDiscard: 'تجاهل',
265
+ keepEditing: 'متابعة التحرير',
266
+ navNoItems: 'لا توجد عناصر تنقل. انقر على الأزرار أعلاه لإضافة عناصر.',
267
+ navNoPreviewItems: 'لا توجد عناصر',
268
+ navLivePreview: 'معاينة مباشرة',
269
+ navCollapseGroup: 'طي المجموعة',
270
+ navExpandGroup: 'توسيع المجموعة',
271
+ navAddChild: 'إضافة عنصر فرعي',
272
+ navMoveUp: 'نقل لأعلى',
273
+ navMoveDown: 'نقل لأسفل',
274
+ navRemove: 'إزالة',
275
+ navObjectPage: 'صفحة الكائن',
276
+ navDashboard: 'لوحة القيادة',
277
+ navPage: 'صفحة',
278
+ navReport: 'تقرير',
279
+ navGroup: 'مجموعة',
280
+ navUrl: 'رابط',
281
+ navSeparator: 'فاصل',
282
+ navTypeObject: 'كائن',
283
+ navTypeDashboard: 'لوحة القيادة',
284
+ navTypePage: 'صفحة',
285
+ navTypeReport: 'تقرير',
286
+ navTypeUrl: 'رابط',
287
+ navTypeGroup: 'مجموعة',
288
+ navTypeSeparator: 'فاصل',
289
+ navTypeAction: 'إجراء',
290
+ navEditIcon: 'تعديل الأيقونة',
291
+ navToggleVisible: 'تبديل الظهور',
292
+ navHidden: 'مخفي',
293
+ navExportSchema: 'تصدير JSON',
294
+ navImportSchema: 'استيراد JSON',
295
+ navExportSuccess: 'تم تصدير هيكل التنقل',
296
+ navImportSuccess: 'تم استيراد هيكل التنقل',
297
+ navImportError: 'ملف JSON تنقل غير صالح',
298
+ navIconPlaceholder: 'اسم الأيقونة (مثل Users)',
299
+ dashboardEditor: 'محرر لوحة المعلومات',
300
+ noWidgets: 'لا توجد عناصر. انقر على زر أعلاه لإضافة واحد.',
301
+ widgetLayoutSize: 'حجم التخطيط',
302
+ widgetWidth: 'العرض',
303
+ widgetHeight: 'الارتفاع',
304
+ dashboardPreview: 'معاينة لوحة المعلومات',
305
+ noWidgetsPreview: 'لا توجد عناصر للمعاينة',
306
+ pageCanvasEditor: 'محرر لوحة الصفحة',
307
+ emptyPage: 'صفحة فارغة. انقر على زر أعلاه لإضافة مكون.',
308
+ pagePreview: 'معاينة الصفحة',
309
+ noComponentsPreview: 'لا توجد مكونات للمعاينة',
310
+ modePage: 'صفحة',
311
+ modeDashboard: 'لوحة المعلومات',
312
+ undo: 'تراجع',
313
+ redo: 'إعادة',
314
+ brandingEditor: 'محرر العلامة التجارية',
315
+ brandingExport: 'تصدير JSON',
316
+ brandingImport: 'استيراد JSON',
317
+ brandingPreview: 'معاينة',
318
+ brandingSampleButton: 'زر نموذجي',
319
+ brandingSampleText: 'هكذا سيبدو موضوع علامتك التجارية.',
320
+ colorPalette: 'لوحة الألوان',
321
+ fontFamily: 'الخط',
322
+ fontDefault: 'افتراضي (النظام)',
323
+ modeLight: 'فاتح',
324
+ modeDark: 'داكن',
325
+ mobilePreview: 'معاينة الجوال',
326
+ },
102
327
  console: {
103
328
  title: 'وحدة تحكم ObjectStack',
104
329
  initializing: 'جاري تهيئة التطبيق...',
330
+ breadcrumb: {
331
+ dashboards: 'لوحات المعلومات',
332
+ pages: 'الصفحات',
333
+ reports: 'التقارير',
334
+ system: 'النظام',
335
+ },
105
336
  loadingSteps: {
106
337
  connecting: 'جاري الاتصال بمصدر البيانات',
107
338
  loadingConfig: 'جاري تحميل الإعدادات',
@@ -136,6 +367,7 @@ const ar = {
136
367
  systemTheme: 'مظهر النظام',
137
368
  actions: 'الإجراءات',
138
369
  openFullSearch: 'فتح صفحة البحث الكاملة',
370
+ createApp: 'إنشاء تطبيق جديد',
139
371
  },
140
372
  errors: {
141
373
  somethingWentWrong: 'حدث خطأ ما',
@@ -162,6 +394,88 @@ const ar = {
162
394
  addView: 'إضافة عرض',
163
395
  designTools: 'أدوات التصميم',
164
396
  new: 'جديد',
397
+ configureView: 'تكوين العرض',
398
+ closePanel: 'إغلاق اللوحة',
399
+ page: 'الصفحة',
400
+ pageConfigHint: 'شريط الأدوات والتنقل وإعدادات غلاف العرض',
401
+ listConfigHint: 'عرض البيانات والأعمدة والمظهر لهذا النوع من القائمة',
402
+ general: 'عام',
403
+ generalHint: 'عنوان العرض والوصف والنوع',
404
+ toolbar: 'شريط الأدوات',
405
+ toolbarHint: 'البحث والتصفية والفرز والتجميع ومفاتيح الكثافة',
406
+ toolbarEnabledCount: '{{count}} of {{total}} enabled',
407
+ navigationSection: 'التنقل',
408
+ navigationHint: 'سلوك النقر على الصف وإعدادات العرض التفصيلي',
409
+ records: 'السجلات',
410
+ recordsHint: 'وضع التحديد وإضافة سجل والتحرير المباشر',
411
+ exportPrint: 'التصدير والطباعة',
412
+ exportPrintHint: 'صيغ التصدير والطباعة وعرض عدد السجلات',
413
+ showAllFields: 'إظهار الكل',
414
+ hideAllFields: 'إخفاء الكل',
415
+ searchFields: 'البحث في الحقول...',
416
+ title: 'العنوان',
417
+ description: 'الوصف',
418
+ data: 'البيانات',
419
+ source: 'المصدر',
420
+ columns: 'الأعمدة',
421
+ filterBy: 'تصفية حسب',
422
+ sortBy: 'ترتيب حسب',
423
+ appearance: 'المظهر',
424
+ showDescription: 'عرض الوصف',
425
+ viewType: 'نوع العرض',
426
+ userFilters: 'مرشحات المستخدم',
427
+ enableSearch: 'تفعيل البحث',
428
+ enableFilter: 'تفعيل التصفية',
429
+ enableSort: 'تفعيل الترتيب',
430
+ enableHideFields: 'تفعيل إخفاء الحقول',
431
+ enableGroup: 'تفعيل التجميع',
432
+ enableColor: 'تفعيل اللون',
433
+ enableDensity: 'تفعيل الكثافة',
434
+ userActions: 'إجراءات المستخدم',
435
+ addRecordViaForm: 'إضافة سجلات عبر النموذج',
436
+ advanced: 'متقدم',
437
+ allowExport: 'السماح بالتصدير',
438
+ recordCount: '{{count}} سجل',
439
+ noDescription: 'لا يوجد وصف',
440
+ none: 'لا شيء',
441
+ columnsConfigured: '{{count}} أعمدة',
442
+ save: 'حفظ',
443
+ discard: 'تجاهل',
444
+ createView: 'إنشاء عرض',
445
+ newView: 'عرض جديد',
446
+ typeOptions: 'خيارات النوع',
447
+ groupByField: 'حقل التجميع',
448
+ startDateField: 'حقل تاريخ البدء',
449
+ titleField: 'حقل العنوان',
450
+ latitudeField: 'حقل خط العرض',
451
+ longitudeField: 'حقل خط الطول',
452
+ imageField: 'حقل الصورة',
453
+ dateField: 'حقل التاريخ',
454
+ selectField: 'اختر حقلاً...',
455
+ gridOptionsHint: 'يستخدم عرض الشبكة الأعمدة المكونة أعلاه.',
456
+ groupBy: 'تجميع حسب',
457
+ prefixField: 'حقل البادئة',
458
+ fields: 'الحقول',
459
+ fieldsVisible: '{{count}} مرئي',
460
+ sortsCount: '{{count}} ترتيبات',
461
+ filtersCount: '{{count}} مرشحات',
462
+ endDateField: 'حقل تاريخ الانتهاء',
463
+ color: 'اللون',
464
+ fieldTextColor: 'لون نص الحقل',
465
+ rowHeight: 'ارتفاع الصف',
466
+ wrapHeaders: 'التفاف العناوين',
467
+ showFieldDescriptions: 'إظهار أوصاف الحقول',
468
+ collapseAllByDefault: 'طي الكل افتراضياً',
469
+ striped: 'صفوف مخططة',
470
+ bordered: 'خلايا محاطة بحدود',
471
+ inlineEdit: 'تحرير السجلات مباشرة',
472
+ addDeleteRecordsInline: 'إضافة/حذف السجلات مباشرة',
473
+ clickIntoRecordDetails: 'انقر لعرض تفاصيل السجل',
474
+ navigationMode: 'وضع التنقل',
475
+ navigationWidth: 'عرض التنقل',
476
+ navigationWidthHint: 'متاح لأوضاع التنقل: الدرج والنافذة المنبثقة والعرض المقسم',
477
+ openNewTab: 'فتح في علامة تبويب جديدة',
478
+ openNewTabHint: 'متاح لأوضاع التنقل: الصفحة والنافذة الجديدة',
165
479
  },
166
480
  localeSwitcher: {
167
481
  label: 'اللغة',