أين يمكن استخدام مكوّنات الواجهة الأمامية
يمكن عرض مكوّنات الواجهة الأمامية في موقعين داخل Twenty:- اللوحة الجانبية — المكوّنات غير عديمة الرأس تفتح في اللوحة الجانبية اليمنى. هذا هو السلوك الافتراضي عندما يتم تشغيل مكوّن واجهة أمامية من قائمة الأوامر.
- الويدجت (لوحات المعلومات وصفحات السجلات) — يمكن تضمين مكوّنات الواجهة الأمامية كويدجت داخل تخطيطات الصفحات. عند تكوين لوحة معلومات أو تخطيط صفحة سجل، يمكن للمستخدمين إضافة ويدجت لمكوّن واجهة أمامية.
- إقرانه مع عنصر قائمة الأوامر — يقوم بتسجيله في قائمة الأوامر (Cmd+K) واختياريًا كإجراء سريع مُثبّت.
- تضمينه كويدجت في تخطيط صفحة — يضعه في صفحة تفاصيل السجل أو لوحة المعلومات.
مثال أساسي
أسرع طريقة لرؤية مكوّن الواجهة الأمامية أثناء العمل هي إقرانه معdefineCommandMenuItem، بحيث يظهر كزر إجراء سريع في الزاوية العلوية اليمنى من الصفحة:
src/front-components/hello-world.tsx
src/command-menu-items/hello-world.command-menu-item.ts
yarn twenty dev (أو تشغيل الأمر لمرة واحدة yarn twenty dev --once)، يظهر الإجراء السريع في الزاوية العلوية اليمنى من الصفحة:

حقول التكوين
| الحقل | مطلوب | الوصف |
|---|---|---|
universalIdentifier | نعم | معرّف فريد ثابت لهذا المكوّن |
component | نعم | دالة مكوّن React |
name | لا | الاسم المعروض |
description | لا | وصف لما يفعله المكوّن |
isHeadless | لا | عيّنه على true إذا كان المكوّن بلا واجهة مرئية (انظر أدناه) |
وضع مكوّن أمامي على صفحة
إضافةً إلى الأوامر، يمكنك تضمين مكوّن أمامي مباشرةً في صفحة سجل عبر إضافته كودجت في تخطيط صفحة. لمزيد من التفاصيل، راجع تخطيطات الصفحات.عديم الرأس مقابل غير عديم الرأس
تأتي مكوّنات الواجهة الأمامية بوضعَي عرض يتحكّم بهما الخيارisHeadless:
غير عديم الرأس (افتراضي) — يعرض المكوّن واجهة مستخدم مرئية. عند تشغيله من قائمة الأوامر يفتح في اللوحة الجانبية. هذا هو السلوك الافتراضي عندما تكون isHeadless تساوي false أو يتم تجاهلها.
عديم الرأس (isHeadless: true) — يتم تركيب المكوّن بشكل غير مرئي في الخلفية. لا يفتح اللوحة الجانبية. تم تصميم المكوّنات عديمة الرأس لإجراءات تنفّذ منطقًا ثم تُزيل تركيبها ذاتيًا — على سبيل المثال، تشغيل مهمة غير متزامنة، أو الانتقال إلى صفحة، أو إظهار نافذة تأكيد منبثقة. تتوافق بشكل طبيعي مع مكوّنات Command في SDK الموصوفة أدناه.
src/front-components/sync-tracker.tsx
null، فإن Twenty يتخطّى عرض حاوية له — ولن تظهر مساحة فارغة في التخطيط. لا يزال لدى المكوّن إمكانية الوصول إلى جميع الخطافات وواجهة برمجة الاتصال مع المضيف.
مكوّنات Command في SDK
توفر حزمةtwenty-sdk أربعة مكوّنات مساعدة من نوع Command مصممة للمكوّنات عديمة الرأس في الواجهة الأمامية. كل مكوّن ينفّذ إجراءً عند التركيب، ويتعامل مع الأخطاء بعرض إشعار Snackbar، ويزيل تركيب مكوّن الواجهة الأمامية تلقائيًا عند الانتهاء.
استوردها من twenty-sdk/command:
Command— يشغّل رد نداء غير متزامن عبر الخاصيةexecute.CommandLink— ينتقل إلى مسار في التطبيق. الخصائص:to،params،queryParams،options.CommandModal— يفتح نافذة تأكيد منبثقة. إذا أكّد المستخدم، ينفّذ رد النداءexecute. الخصائص:title،subtitle،execute،confirmButtonText،confirmButtonAccent.CommandOpenSidePanelPage— يفتح صفحة محدّدة في اللوحة الجانبية. الخصائص:page،pageTitle،pageIcon.
Command لتشغيل إجراء من قائمة الأوامر:
src/front-components/run-action.tsx
src/command-menu-items/run-action.command-menu-item.ts
CommandModal لطلب التأكيد قبل التنفيذ:
src/front-components/delete-draft.tsx
استدعاء دالة منطقية
تعمل مكونات الواجهة الأمامية في المتصفح داخل Web Worker معزول، بينما تعمل الدوال المنطقية على جانب الخادم. لا توجد استدعاءات مباشرة ضمن العملية بين الاثنين — بدلاً من ذلك، يصل مكون الواجهة الأمامية إلى الدالة المنطقية عبر HTTP. يتم إتاحة الدالة المنطقية المُعلَنة باستخدامhttpRouteTriggerSettings تحت نقطة النهاية /s/ عند ${TWENTY_API_URL}/s\<path>. يستدعي مكون الواجهة الأمامية ذلك المسار باستخدام RestApiClient من twenty-client-sdk/rest، والذي يقوم بالمصادقة باستخدام TWENTY_APP_ACCESS_TOKEN الذي تقوم Twenty بحقنه في الـ worker.
تم تصميم RestApiClient خصيصًا لهذا الغرض. يقوم بقراءة TWENTY_API_URL وTWENTY_APP_ACCESS_TOKEN من بيئة الـ worker، وإرفاق ترويسة Authorization: Bearer، وتسلسل وتحليل JSON، وإثارة RestApiClientError عندما يكون الرمز المميز أو عنوان URL مفقودًا أو عندما يكون الرد غير 2xx — حتى لا تعيد تنفيذ هذا الـ boilerplate في كل مكون.
يمكن لمكون واجهة أمامية عديم الرأس تنفيذ الاستدعاء عند التركيب عبر مكون Command، ثم إلغاء التركيب تلقائيًا:
src/front-components/sync-prs.tsx
httpRouteTriggerSettings.path الخاصة بدالة المنطق (logic function) مع إضافة البادئة /s. أبقِ isAuthRequired: true؛ يزوّد العميل مكوّنك برمز وصول التطبيق الذي تُصدِره Twenty:
src/logic-functions/fetch-prs.logic-function.ts
يتم حقن
TWENTY_API_URL وTWENTY_APP_ACCESS_TOKEN تلقائيًا — انظر متغيرات التطبيق. نظرًا لأن متغيرات التطبيق السرية لا تُعرَض أبدًا على مكونات الواجهة الأمامية، احتفِظ بمفاتيح واجهة برمجة التطبيقات والمنطق الحساس الآخر داخل الدالة المنطقية، وليس في مكون الواجهة الأمامية.مرجع RestApiClient
استوردRestApiClient من twenty-client-sdk/rest. ينتمي إلى نفس عائلة العملاء مثل CoreApiClient وMetadataApiClient، لكنه يستهدف مسارات HTTP الخاصة بتطبيقك بدلاً من واجهة GraphQL API.
| طريقة | الوصف |
|---|---|
get(path, options?) | يرسل طلبًا من نوع GET |
post(path, body?, options?) | يرسل طلبًا من نوع POST |
put(path, body?, options?) | يرسل طلبًا من نوع PUT |
patch(path, body?, options?) | يرسل طلبًا من نوع PATCH |
delete(path, options?) | يرسل طلبًا من نوع DELETE |
request(method, path, options?) | طلب عام بأي طريقة HTTP |
options كلًا من headers وquery (سجل لمعاملات query-string؛ يتم تخطي القيم nullish) وAbortSignal عبر signal. يتم تسلسل كائن body غير من النوع FormData إلى JSON تلقائيًا. عند حدوث 401، يقوم العميل بتحديث رمز الوصول مرة واحدة عبر المضيف ثم يعيد محاولة الطلب.
يتم تحديد عنوان URL الأساسي والرمز من بيئة التشغيل بشكل افتراضي. مرِّر معاملات تجاوز (overrides) إلى المُنشئ (constructor) عند الحاجة — على سبيل المثال في الاختبارات:
RestApiClientError يعرِّض خصائص status وstatusText وurl بالإضافة إلى body بعد تحليله (parsed):
الوصول إلى سياق وقت التشغيل
داخل مكوّنك، استخدم خطافات SDK للوصول إلى المستخدم الحالي، والسجل، ومثيل المكوّن:src/front-components/record-info.tsx
| الخطّاف | القيم المعادة | الوصف |
|---|---|---|
useUserId() | string أو null | معرّف المستخدم الحالي |
useSelectedRecordIds() | string[] | جميع معرّفات السجلات المحددة (مصفوفة فارغة إذا لم يتم تحديد أي منها) |
useRecordId() | string أو null | مهمل. استخدم useSelectedRecordIds() بدلاً من ذلك |
useFrontComponentId() | string | معرّف مثيل هذا المكوّن |
useColorScheme() | 'light' أو 'dark' | نظام الألوان النشط لواجهة المستخدم المضيفة (System تم تحديده بالفعل) |
useFrontComponentExecutionContext(selector) | يختلف | الوصول إلى سياق التنفيذ الكامل عبر دالة محدِّد |
متغيرات التطبيق
متغيرات التطبيق المُعرَّفة فيdefineApplication() مع isSecret: false تكون متاحة داخل مكوّنات الواجهة عبر أداة getApplicationVariable:
src/front-components/greeting.tsx
process.env:
| المتغيّر | الوصف |
|---|---|
TWENTY_API_URL | عنوان URL الأساسي لـ Twenty API |
TWENTY_APP_ACCESS_TOKEN | رمز مميز قصير العمر مُقيَّد بدور تطبيقك |
واجهة الاتصال مع المضيف
يمكن للمكوّنات الأمامية تشغيل التنقّل والنوافذ المنبثقة والإشعارات باستخدام دوال منtwenty-sdk:
| دالة | الوصف |
|---|---|
navigate(to, params?, queryParams?, options?) | الانتقال إلى صفحة داخل التطبيق |
openSidePanelPage(params) | فتح لوحة جانبية |
closeSidePanel() | إغلاق اللوحة الجانبية |
openCommandConfirmationModal(params) | عرض مربع حوار تأكيد |
enqueueSnackbar(params) | عرض إشعار توست |
unmountFrontComponent() | إلغاء تركيب المكوّن |
updateProgress(progress) | تحديث مؤشّر التقدّم |
src/front-components/archive-record.tsx
العمل مع سجلات متعددة
استخدمuseSelectedRecordIds() لمعالجة عدة سجلات محددة. هذا مفيد للعمليات المجمّعة:
src/front-components/bulk-export.tsx
الأصول العامة
يمكن للمكوّنات الأمامية الوصول إلى ملفات من دليلpublic/ للتطبيق باستخدام getPublicAssetUrl:
التنسيق
تدعم المكوّنات الأمامية عدة أساليب للتنسيق. يمكنك استخدام:- أنماط مضمنة —
style={{ color: 'red' }} - مكوّنات Twenty لواجهة المستخدم — استورد من
twenty-sdk/ui(Button وTag وStatus وChip وAvatar وغيرها) - Emotion — CSS-in-JS مع
@emotion/react - Styled-components — أنماط
styled.div - Tailwind CSS — أصناف مساعدة
- أي مكتبة CSS-in-JS متوافقة مع React