بناء مدير مهام
المصدر:
tests/schemas/09-full-app.orb
هذا التعليمي يبني مدير مهام حقيقي خطوة بخطوة. بنهايته سيكون لديك برنامج يحتوي على:
- كيان (Entity)
Taskمع استمرارية - سمة دورة حياة (آلة حالة لحالة المهمة)
- سمة CRUD (قائمة، إنشاء، تعديل، حذف)
- صفحتان مربوطتان بالسمات
Orbital Unit = Entity + Traits + Pages
ما الذي نبنيه
/tasks → TaskListPage (تصفح، إنشاء، تعديل، حذف المهام)
/tasks/:id → التنقل إليها من القائمة (عرض التفاصيل)
الوحدة المدارية TaskManager لها كيان واحد (Task) وسمتان: واحدة لدورة حياة حالة المهمة، وأخرى لإدارة القائمة.
الخطوة 1 - كيان المهمة (Task Entity)
{
"اسم": "Task",
"استمرارية": "دائم",
"مجموعة": "tasks",
"حقول": [
{
"اسم": "id",
"نوع": "نص",
"مطلوب": true
},
{
"اسم": "title",
"نوع": "نص",
"مطلوب": true
},
{
"اسم": "description",
"نوع": "نص"
},
{
"اسم": "priority",
"نوع": "تعداد",
"قيم": [
"low",
"medium",
"high"
],
"افتراضي": "medium"
},
{
"اسم": "dueDate",
"نوع": "تاريخ"
},
{
"اسم": "assigneeId",
"نوع": "نص"
},
{
"اسم": "projectId",
"نوع": "نص"
}
]
}
persistence: "persistent" يعني أن هذا مخزن في قاعدة البيانات. مفتاح collection يحدد اسم مجموعة/جدول قاعدة البيانات.
الخطوة 2 - سمة دورة الحياة (Lifecycle Trait)
سمة TaskLifecycle تتتبع موقع المهمة في سير العمل: todo → inProgress → review → done.
{
"اسم": "TaskLifecycle",
"كيان_مرتبط": "Task",
"فئة": "interaction",
"آلة_حالة": {
"حالات": [
{
"اسم": "todo",
"أولي": true
},
{
"اسم": "inProgress"
},
{
"اسم": "review"
},
{
"اسم": "done",
"نهائي": true,
"وصف": "Task completed"
}
],
"أحداث": [
{
"مفتاح": "INIT",
"اسم": "Initialize"
},
{
"مفتاح": "START",
"اسم": "Start Task"
},
{
"مفتاح": "SUBMIT_FOR_REVIEW",
"اسم": "Submit for Review"
},
{
"مفتاح": "APPROVE",
"اسم": "Approve"
},
{
"مفتاح": "REJECT",
"اسم": "Request Changes"
},
{
"مفتاح": "COMPLETE",
"اسم": "Complete"
}
],
"انتقالات": [
{
"من": "todo",
"حدث": "INIT",
"إلى": "todo",
"تأثيرات": [
[
"جلب",
"Task"
],
[
"عرض_واجهة",
"main",
{
"نوع": "stats",
"عناصر": [
{
"تسمية": "Todo",
"value": "@كيان.todo"
},
{
"تسمية": "In Progress",
"value": "@كيان.inProgress"
},
{
"تسمية": "Done",
"value": "@كيان.done"
}
]
}
]
]
},
{
"من": "todo",
"حدث": "START",
"إلى": "inProgress"
},
{
"من": "inProgress",
"حدث": "SUBMIT_FOR_REVIEW",
"إلى": "review"
},
{
"من": "review",
"حدث": "APPROVE",
"إلى": "done",
"تأثيرات": [
[
"بث",
"TASK_COMPLETED",
{
"taskId": "@كيان.id",
"projectId": "@كيان.projectId"
}
]
]
},
{
"من": "review",
"حدث": "REJECT",
"إلى": "inProgress"
},
{
"من": "inProgress",
"حدث": "COMPLETE",
"إلى": "done",
"تأثيرات": [
[
"بث",
"TASK_COMPLETED",
{
"taskId": "@كيان.id",
"projectId": "@كيان.projectId"
}
]
]
}
]
}
}
أنماط ملحوظة:
- الحلقة الذاتية
INITتعرض لوحةstatsتوضح العدد حسب الحالة isTerminal: trueعلىdoneيعني أنه لا يُسمح بانتقالات إضافية من تلك الحالةemitتنشر حدثاً عبر الوحدات المدارية (انظر التواصل عبر الوحدات المدارية)
الخطوة 3 - سمة CRUD
سمة TaskCRUD تعالج واجهة إدارة القائمة: عرض القائمة، الإنشاء، التعديل، والحذف.
{
"اسم": "TaskCRUD",
"كيان_مرتبط": "Task",
"فئة": "interaction",
"آلة_حالة": {
"حالات": [
{
"اسم": "listing",
"أولي": true
},
{
"اسم": "creating"
},
{
"اسم": "editing"
}
],
"أحداث": [
{
"مفتاح": "INIT",
"اسم": "Initialize"
},
{
"مفتاح": "VIEW",
"اسم": "View Task",
"حمولة": [
{
"اسم": "id",
"نوع": "نص",
"مطلوب": true
}
]
},
{
"مفتاح": "CREATE",
"اسم": "Create Task"
},
{
"مفتاح": "EDIT",
"اسم": "Edit Task"
},
{
"مفتاح": "SAVE",
"اسم": "Save"
},
{
"مفتاح": "CANCEL",
"اسم": "Cancel"
},
{
"مفتاح": "DELETE",
"اسم": "Delete Task"
}
],
"انتقالات": [
{
"من": "listing",
"حدث": "INIT",
"إلى": "listing",
"تأثيرات": [
[
"جلب",
"Task"
],
[
"عرض_واجهة",
"main",
{
"نوع": "entity-table",
"كيان": "Task",
"columns": [
"title",
"priority",
"dueDate"
],
"itemActions": [
{
"حدث": "VIEW",
"تسمية": "View"
},
{
"حدث": "EDIT",
"تسمية": "Edit"
},
{
"حدث": "DELETE",
"تسمية": "Delete"
}
]
}
]
]
},
{
"من": "listing",
"حدث": "CREATE",
"إلى": "creating",
"تأثيرات": [
[
"عرض_واجهة",
"main",
{
"نوع": "form",
"كيان": "Task"
}
]
]
},
{
"من": "creating",
"حدث": "SAVE",
"إلى": "listing",
"تأثيرات": [
[
"حفظ",
"update",
"Task",
"@كيان"
],
[
"إشعار",
"success",
"Task created"
]
]
},
{
"من": "creating",
"حدث": "CANCEL",
"إلى": "listing"
},
{
"من": "listing",
"حدث": "EDIT",
"إلى": "editing"
},
{
"من": "editing",
"حدث": "SAVE",
"إلى": "listing",
"تأثيرات": [
[
"حفظ",
"update",
"Task",
"@كيان"
]
]
},
{
"من": "editing",
"حدث": "CANCEL",
"إلى": "listing"
},
{
"من": "listing",
"حدث": "DELETE",
"إلى": "listing",
"تأثيرات": [
[
"حفظ",
"delete",
"Task",
"@كيان.id"
],
[
"إشعار",
"info",
"Task deleted"
]
]
},
{
"من": "listing",
"حدث": "VIEW",
"إلى": "listing",
"تأثيرات": [
[
"انتقال",
"/tasks/@payload.id"
]
]
}
]
}
}
ما تفعله آلة الحالة:
listing- INIT يعرض الجدول. المستخدم يمكنه VIEW أو CREATE أو EDIT أو DELETE من هنا.creating- ينتقل إلى نموذج؛ SAVE يحفظ ويعود للقائمة، CANCEL يعودediting- نفس نمط creating لكن لسجل موجودVIEWيتنقل إلى صفحة التفاصيل باستخدامidمن الحمولة
الحمولة في الأحداث: حدث VIEW يحمل id ليعرف وقت التشغيل أي مهمة تم النقر عليها. يمكن الوصول إليها في التأثيرات بـ @payload.id.
الخطوة 4 - إضافة الصفحات (Pages)
"pages": [
{
"name": "TaskListPage",
"path": "/tasks",
"traits": [{ "ref": "TaskCRUD", "linkedEntity": "Task" }]
}
]
التحقق والتشغيل
# التحقق من البرنامج
orb validate schema.orb
# بدء خادم التطوير
orb dev
انتقل إلى http://localhost:3000/tasks لرؤية مدير المهام.
الخطوات التالية
- أنماط الواجهة وrender-ui - تعمق أكثر في
entity-tableوformوغيرها - الحراس وقواعد العمل - تقييد من يمكنه إكمال أو حذف المهام
- التواصل عبر الوحدات المدارية - ربط TaskManager بـ ProjectManager
- بناء تطبيق كامل - التطبيق الكامل من 3 وحدات مدارية