@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.
- package/.turbo/turbo-build.log +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.js +2 -0
- package/dist/locales/ar.d.ts +314 -0
- package/dist/locales/ar.js +314 -0
- package/dist/locales/de.d.ts +314 -0
- package/dist/locales/de.js +314 -0
- package/dist/locales/en.d.ts +372 -0
- package/dist/locales/en.js +372 -0
- package/dist/locales/es.d.ts +314 -0
- package/dist/locales/es.js +314 -0
- package/dist/locales/fr.d.ts +314 -0
- package/dist/locales/fr.js +314 -0
- package/dist/locales/index.d.ts +3256 -0
- package/dist/locales/ja.d.ts +314 -0
- package/dist/locales/ja.js +314 -0
- package/dist/locales/ko.d.ts +314 -0
- package/dist/locales/ko.js +314 -0
- package/dist/locales/pt.d.ts +314 -0
- package/dist/locales/pt.js +314 -0
- package/dist/locales/ru.d.ts +314 -0
- package/dist/locales/ru.js +314 -0
- package/dist/locales/zh.d.ts +372 -0
- package/dist/locales/zh.js +372 -0
- package/dist/provider.js +34 -4
- package/dist/useObjectLabel.d.ts +61 -0
- package/dist/useObjectLabel.js +114 -0
- package/package.json +3 -3
- package/src/__tests__/useObjectLabel.test.tsx +131 -0
- package/src/index.ts +3 -0
- package/src/locales/ar.ts +314 -0
- package/src/locales/de.ts +314 -0
- package/src/locales/en.ts +372 -0
- package/src/locales/es.ts +314 -0
- package/src/locales/fr.ts +314 -0
- package/src/locales/ja.ts +314 -0
- package/src/locales/ko.ts +314 -0
- package/src/locales/pt.ts +314 -0
- package/src/locales/ru.ts +314 -0
- package/src/locales/zh.ts +372 -0
- package/src/provider.tsx +33 -4
- package/src/useObjectLabel.ts +122 -0
- 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: 'اللغة',
|