الانتقال إلى المحتوى الرئيسي
يُعَدّ عنصر قائمة الأوامر الجسر بين المستخدم ومكوّن الواجهة الأمامية. يسجّل هذا العنصر المكوّن في قائمة الأوامر في Twenty‏ (Cmd+K)، وبشكل اختياري، كزر إجراء سريع مُثبَّت في الزاوية العلوية اليمنى من الصفحة.
src/command-menu-items/open-dashboard.command-menu-item.ts
import { defineCommandMenuItem } from 'twenty-sdk/define';

export default defineCommandMenuItem({
  universalIdentifier: 'a1b2c3d4-e5f6-7890-abcd-ef1234567890',
  label: 'Open Dashboard',
  shortLabel: 'Dashboard',
  icon: 'IconLayoutDashboard',
  isPinned: true,
  availabilityType: 'GLOBAL',
  frontComponentUniversalIdentifier: '74c526eb-cb68-4cf7-b05c-0dd8c288d948',
});

حقول التكوين

الحقلمطلوبالوصف
universalIdentifierنعممعرّف فريد ثابت للأمر
labelنعمالتسمية الكاملة المعروضة في قائمة الأوامر (Cmd+K)
frontComponentUniversalIdentifierنعمقيمة universalIdentifier للمكوّن الأمامي الذي يفتحه هذا الأمر
shortLabelلاتسمية أقصر تُعرَض على زر الإجراء السريع المثبّت
iconلااسم الأيقونة المعروض بجانب التسمية (مثل 'IconBolt' و'IconSend')
isPinnedلاعند كونها true، يعرض الأمر كزر إجراء سريع في الزاوية العلوية اليمنى من الصفحة
availabilityTypeلاتتحكّم في مكان ظهور الأمر: 'GLOBAL' (متاح دائمًا)، و'RECORD_SELECTION' (فقط عند تحديد سجلات)، أو 'FALLBACK' (يُعرَض عند عدم تطابق أي أوامر أخرى)
availabilityObjectUniversalIdentifierلاتقييد الأمر بصفحات نوع كائن معيّن (مثل سجلات Company فقط)
conditionalAvailabilityExpressionلاتعبير منطقي يتحكّم ديناميكيًا في الظهور (انظر أدناه)

أوامر بدون واجهة

يُعَدّ عنصر قائمة الأوامر المقترن بـمكوّن واجهة أمامية بدون واجهة الطريقة القياسية لتوفير إجراء بنقرة واحدة — لتشغيل الشفرة أو التنقّل أو التأكيد ثم التنفيذ. تغطي صفحة مكوّنات الواجهة الأمامية مكوّنات الأوامر في SDK ‎(Command, CommandLink, CommandModal, CommandOpenSidePanelPage)‎ التي تتعامل مع نمط الإجراء-ثم-إلغاء التركيب. تدفق نموذجي:
src/front-components/run-action.tsx
import { defineFrontComponent } from 'twenty-sdk/define';
import { Command } from 'twenty-sdk/command';
import { CoreApiClient } from 'twenty-sdk/clients';

const RunAction = () => {
  const execute = async () => {
    const client = new CoreApiClient();
    await client.mutation({
      createTask: {
        __args: { data: { title: 'Created by my app' } },
        id: true,
      },
    });
  };

  return <Command execute={execute} />;
};

export default defineFrontComponent({
  universalIdentifier: 'e5f6a7b8-c9d0-1234-efab-345678901234',
  name: 'run-action',
  description: 'Creates a task from the command menu',
  component: RunAction,
  isHeadless: true,
});
src/command-menu-items/run-action.command-menu-item.ts
import { defineCommandMenuItem } from 'twenty-sdk/define';

export default defineCommandMenuItem({
  universalIdentifier: 'f6a7b8c9-d0e1-2345-fabc-456789012345',
  label: 'Run my action',
  icon: 'IconPlayerPlay',
  frontComponentUniversalIdentifier: 'e5f6a7b8-c9d0-1234-efab-345678901234',
});

تعابير الإتاحة الشرطية

يتيح لك الحقل conditionalAvailabilityExpression التحكّم في وقت ظهور الأمر بناءً على سياق الصفحة الحالي. استورد متغيّرات ومشغّلات مضبوطة الأنواع من twenty-sdk لبناء التعابير:
src/command-menu-items/bulk-update.command-menu-item.ts
import {
  defineCommandMenuItem,
  objectPermissions,
  everyEquals,
} from 'twenty-sdk/define';

export default defineCommandMenuItem({
  universalIdentifier: '...',
  label: 'Bulk Update',
  availabilityType: 'RECORD_SELECTION',
  frontComponentUniversalIdentifier: '...',
  conditionalAvailabilityExpression: everyEquals(
    objectPermissions,
    'canUpdateObjectRecords',
    true,
  ),
});
RECORD_SELECTION تعني بالفعل وجود تحديد غير فارغ — استخدم numberOfSelectedRecords فقط لعرض الأعداد المحددة (على سبيل المثال >= 2).

متغيّرات السياق

تُمثّل هذه المتغيّرات الحالة الحالية للصفحة:
المتغيّرالنوعالوصف
pageTypestringنوع الصفحة الحالي (مثل 'RecordIndexPage' و'RecordShowPage')
isInSidePanelbooleanما إذا كان المكوّن معروضًا في لوحة جانبية
numberOfSelectedRecordsnumberعدد السجلات المحدّدة حاليًا
isSelectAllbooleanما إذا كان “تحديد الكل” مفعّلًا
selectedRecordsarrayكائنات السجلات المحدّدة
favoriteRecordIdsarrayمعرّفات السجلات المفضّلة
objectPermissionsobjectالأذونات الخاصة بنوع الكائن الحالي
targetObjectReadPermissionsobjectأذونات القراءة للكائن الهدف
targetObjectWritePermissionsobjectأذونات الكتابة للكائن الهدف
featureFlagsobjectأعلام الميزات المفعَّلة
objectMetadataItemobjectبيانات التعريف لنوع الكائن الحالي
hasAnySoftDeleteFilterOnViewbooleanما إذا كان العرض الحالي يحتوي على مرشّح حذف منطقي

المُشغِّلات

جمّع المتغيّرات في تعابير منطقية:
المُشغِّلالوصف
isDefined(value)true إذا لم تكن القيمة null/undefined
isNonEmptyString(value)true إذا كانت القيمة سلسلة غير فارغة
includes(array, value)true إذا كانت المصفوفة تحتوي على القيمة
includesEvery(array, prop, value)true إذا كانت خاصية كل عنصر تتضمن القيمة
every(array, prop)true إذا كانت الخاصية تُقيَّم كقيمة صادقة في كل عنصر
everyDefined(array, prop)true إذا كانت الخاصية معرّفة في كل عنصر
everyEquals(array, prop, value)true إذا كانت الخاصية تساوي القيمة في كل عنصر
some(array, prop)true إذا كانت الخاصية تُقيَّم كقيمة صادقة في عنصر واحد على الأقل
someDefined(array, prop)true إذا كانت الخاصية معرّفة في عنصر واحد على الأقل
someEquals(array, prop, value)true إذا كانت الخاصية تساوي القيمة في عنصر واحد على الأقل
someNonEmptyString(array, prop)true إذا كانت الخاصية سلسلة غير فارغة في عنصر واحد على الأقل
none(array, prop)true إذا كانت الخاصية تُقيَّم كقيمة زائفة في كل عنصر
noneDefined(array, prop)true إذا كانت الخاصية غير معرّفة في كل عنصر
noneEquals(array, prop, value)true إذا لم تكن الخاصية تساوي القيمة في أي عنصر