الانتقال إلى المحتوى الرئيسي

نظرة عامة

تُعد الكائنات المخصصة أنواع سجلات جديدة يضيفها تطبيقك إلى مساحة العمل — مثل بطاقة بريدية، أو فاتورة، أو اشتراك، أو أي شيء خاص بالمجال الذي تعمل فيه. يعلن كل كائن عن مخططه (الحقول، والعلاقات، والقيم الافتراضية) ومعرّف عالمي ثابت يستمر عبر عمليات المزامنة والنشر.
src/objects/post-card.object.ts

النقاط الرئيسية

  • universalIdentifier يجب أن يكون فريدًا وثابتًا عبر عمليات النشر.
  • يتطلب كل حقل name وtype وlabel ومعرّف universalIdentifier ثابتًا خاصًا به.
  • المصفوفة fields اختيارية — يمكنك تعريف كائنات بدون حقول مخصصة.
  • openRecordIn يحدد أين تُفتح سجلات هذا الكائن عند النقر عليها: ObjectOpenRecordIn.USER_CHOICE (الإعداد الافتراضي، الذي يتبع تفضيل كل عضو في مساحة العمل من Settings → Experience)، أو ObjectOpenRecordIn.SIDE_PANEL، أو ObjectOpenRecordIn.RECORD_PAGE. ثبِّتها على RECORD_PAGE للسجلات التي تحتاج إلى صفحة كاملة لتكون قابلة للاستخدام، كما هو الحال في سير العمل ولوحات المعلومات، أو على SIDE_PANEL للسجلات التي لا تكون منطقية إلا كلوحة سريعة، كما هو الحال في أحداث التقويم.
  • يسرد disabledObjectPermissionActions أذونات الكائن التي لا يمكن منحها على الكائن: أي من 'canReadObjectRecords' و'canUpdateObjectRecords' و'canSoftDeleteObjectRecords' و'canDestroyObjectRecords'، وهي العلامات نفسها التي يعيّنها الدور لكل كائن. لا يحصل المستخدمون ومفاتيح API والوكلاء مطلقًا على هذه الإجراءات على الكائن، مهما كانت الصلاحيات التي يمنحها دورهم، ويفشل حفظ إذن كائن يمنح أحدها. تحتفظ بها دوال المنطق الخاصة بتطبيقك. على سبيل المثال، يجعل ['canUpdateObjectRecords', 'canSoftDeleteObjectRecords', 'canDestroyObjectRecords'] الكائن قابلًا للكتابة بواسطة تطبيقك فقط، للسجلات الشبيهة بالإعدادات التي تمنح سلوكًا.
  • يضبط color لون الإبراز للكائن في واجهة المستخدم. احذفه، وسيختار Twenty واحدًا للكائن.
  • يسمّي imageIdentifierFieldMetadataUniversalIdentifier الحقل الذي تُعرض قيمته بوصفها الصورة الرمزية للسجل. احذفه للسماح لـ Twenty باختيار القيمة الافتراضية.
  • يحافظ isLabelSyncedWithName، على كائن أو حقل، على مزامنة اسم API مع التسمية عند تحرير التسمية في الإعدادات. تكون القيمة الافتراضية false، لذا تترك التسمية المعاد تسميتها الاسم دون تغيير.
  • يؤدي isSearchable: true في حقل إلى تضمين قيمه في البحث النصي الكامل للكائن (البحث العام وقائمة الأوامر). يتطلب ذلك أن يكون الكائن نفسه قابلاً للبحث وأن يكون نوع الحقل متوافقًا مع النص. تعني القيمة المحذوفة أنه غير قابل للبحث، باستثناء حقل معرّف تسمية الكائن، الذي يكون قابلاً للبحث دائمًا ولا يمكن إلغاء الاشتراك فيه. تفرض كل مزامنة الحالة المُعلنة، لذا فإن الحقل الذي تم تبديله ليصبح قابلاً للبحث من الإعدادات يعود إلى حالته السابقة عند مزامنة تطبيقك التالية ما لم يعلن ملف البيان عنه.
  • يؤدي تعيين isAuditLogged: false في حقل إلى إبقاء تغييراته خارج الخط الزمني للسجل. تكون قيمته الافتراضية true، باستثناء حقل POSITION، إذ تظهر تغييراته فارغة في الخط الزمني ولا يتم تسجيلها مطلقًا. عيّنه في الحقول التي يعيد تطبيقك كتابتها وفق جدول زمني، مثل طابع زمني لآخر اتصال أو علاقة تجميع، كي لا تضيف كل مزامنة صف نشاط إلى كل سجل تلمسه. لا ينتج عن تحديث يتكوّن فرقُه بالكامل من حقول غير مسجلة للتدقيق أي نشاط في الخط الزمني على الإطلاق. مثل isSearchable، تفرض كل عملية مزامنة الحالة المُعلنة.
  • يسرد disabledFieldPermissionActions، في حقل، أذونات الحقل التي لا يمكن منحها عليه: 'canReadFieldValue' أو 'canUpdateFieldValue' أو كليهما، وهي العلامات نفسها التي يعيّنها الدور لكل حقل. لا يحصل المستخدمون ومفاتيح API والوكلاء والتطبيقات الأخرى مطلقًا على هذه الإجراءات في الحقل، بغض النظر عما يمنحه دورهم، ويفشل حفظ إذن حقل يمنح أحدها. تحتفظ دوال المنطق الخاصة بتطبيقك بها. على سبيل المثال، يُبقي ['canUpdateFieldValue'] قيمةً يحسبها تطبيقك أو يزامنها، مثل الحالة أو النتيجة، للقراءة فقط للجميع الآخرين. يعمل هذا أيضًا على الحقول التي تضيفها إلى كائنات لا تملكها باستخدام defineField().
  • لا تحتاج الحقول المضمّنة المُعرَّفة هنا إلى objectUniversalIdentifier — إذ تُورَّث من الكائن الأب. استخدم defineField() لإضافة حقول إلى كائنات لا تمتلكها.
  • يمكنك إنشاء كائنات جديدة باستخدام twenty app add object، الذي يرشدك خلال التسمية والحقول والعلاقات. راجع Architecture → Scaffolding entities.
تُضاف الحقول الأساسية تلقائيًا. عند تعريف كائن مخصص، ينشئ Twenty حقولًا قياسية مثل id وname وcreatedAt وupdatedAt وcreatedBy وupdatedBy وdeletedAt من أجلك. لا تحتاج إلى تعريفها في مصفوفة fields — أضف فقط حقولك المخصصة. يمكنك تجاوز حقل افتراضي بتعريف حقل يحمل الاسم نفسه، لكن هذا نادرًا ما يكون فكرة جيدة.

أنواع الحقول

مجموعة القيم الكاملة لـFieldType، والمصدَّرة من twenty-sdk/define: تُخزِّن الأنواع المركّبة عدّة حقول فرعية (مثلًا FULL_NAME = الاسم الأول + اسم العائلة؛ CURRENCY = amountMicros + currencyCode). SELECT وMULTI_SELECT يتطلّبان مصفوفة options كما في المثال أعلاه.

حدد الخيارات

بالنسبة إلى SELECT وMULTI_SELECT، وفّر مصفوفة options غير فارغة من الكائنات. يحتوي كل خيار على value وlabel وposition. color الخاص به اختياري وتكون قيمته الافتراضية gray عند حذفه أو عندما تكون قيمته null. عند توفيره، يجب أن يكون color واحدًا مما يلي: red، ruby، crimson، tomato، orange، amber، yellow، lime، grass، green، jade، mint، turquoise، cyan، sky، blue، iris، violet، purple، plum، pink، bronze، gold، brown، gray. يُرجع كلٌّ من defineObject() وdefineField() أخطاء تحقق للألوان غير المدعومة أو لإدخالات الخيارات التي تكون null أو قيمًا أولية أو مصفوفات.

القيم الافتراضية

يجب تضمين القيم النصية الافتراضية بين علامات اقتباس أحادية داخل السلسلة — defaultValue: "'Draft'"، وليس defaultValue: "Draft". لهذا السبب يستخدم الحقل status أعلاه `'${PostCardStatus.DRAFT}'`. السلاسل غير المحاطة بعلامات اقتباس محجوزة للقيم الافتراضية المحسوبة، والتي يتم تقييمها عند إنشاء سجل:
  • 'uuid' — يُنشِئ UUID (لحقول UUID)
  • 'now' — الطابع الزمني الحالي (لحقول DATE_TIME)
ينطبق نفس الاصطلاح على الحقول الفرعية النصية للقيم الافتراضية المركّبة (على سبيل المثال { source: "'MANUAL'" } في حقل ACTOR) وكذلك على قيم SELECT/MULTI_SELECT. سيتسبّب ترك قيمة افتراضية نصية حرفية بدون علامات اقتباس في ظهور تحذير عند إنشاء التطبيق.

قابلية قبول NULL

isNullable تتحكم في ما إذا كان الحقل يقبل NULL. القيمة الافتراضية هي true — يمكنك حذفها من الحقول الاختيارية. عيِّن isNullable: false لجعل الحقل مطلوبًا على مستوى قاعدة البيانات. يتم تطبيق التغييرات على isNullable في كل عملية مزامنة، بما في ذلك عمليات المزامنة التي تحدّث حقلًا موجودًا — وبالتالي يمكنك تبديل قابلية الحقل لقبول NULL عن طريق تعديل ملف manifest وإعادة المزامنة.
جعل حقل موجود غير قابل لأن يكون فارغًا يتطلب قيمة افتراضية. عندما تغيّر حقلًا إلى isNullable: false، يجب أيضًا توفير defaultValue غير فارغ. تملأ القيمة الافتراضية أي صفوف موجودة تحتوي على NULL قبل تطبيق القيد NOT NULL؛ ومن دونها تفشل المزامنة مع الخطأ Default value cannot be null for non-nullable fields. تكون حقول العلاقات وحقول TS_VECTOR قابلة لأن تكون فارغة دائمًا، لذلك لا يكون لـ isNullable أي تأثير عليها.

ماذا بعد؟

  • اربط هذا الكائن بغيره من الكائنات — راجع صفحة Relations لمعرفة نمط العلاقة ثنائية الاتجاه.
  • أضف حقولًا إلى الكائنات التابعة لتطبيقات أخرى — راجع Extending Objects لمعرفة المزيد حول defineField().
  • اعرض هذا الكائن في واجهة المستخدم (UI) — راجع عناصر قائمة التنقل لإضافة عنصر في الشريط الجانبي؛ وراجع طرق العرض لإضافة تكوينات قوائم مخصصة.