@ -0,0 +1 @@ |
|||
Please describe the feature need! |
|||
@ -0,0 +1,71 @@ |
|||
# For most projects, this workflow file will not need changing; you simply need |
|||
# to commit it to your repository. |
|||
# |
|||
# You may wish to alter this file to override the set of languages analyzed, |
|||
# or to provide custom queries or build logic. |
|||
name: "CodeQL" |
|||
|
|||
on: |
|||
push: |
|||
branches: [dev, rel-1.0, rel-1.1, rel-2.0, rel-2.1, rel-2.2, rel-2.3, rel-2.4, rel-2.5, rel-2.6, rel-2.7, rel-2.8, rel-2.9, rel-3.0, rel-3.1, rel-3.2] |
|||
pull_request: |
|||
# The branches below must be a subset of the branches above |
|||
branches: [dev] |
|||
schedule: |
|||
- cron: '0 8 * * 6' |
|||
|
|||
jobs: |
|||
analyze: |
|||
name: Analyze |
|||
runs-on: ubuntu-latest |
|||
|
|||
strategy: |
|||
fail-fast: false |
|||
matrix: |
|||
# Override automatic language detection by changing the below list |
|||
# Supported options are ['csharp', 'cpp', 'go', 'java', 'javascript', 'python'] |
|||
language: ['csharp', 'javascript'] |
|||
# Learn more... |
|||
# https://docs.github.com/en/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#overriding-automatic-language-detection |
|||
|
|||
steps: |
|||
- name: Checkout repository |
|||
uses: actions/checkout@v2 |
|||
with: |
|||
# We must fetch at least the immediate parents so that if this is |
|||
# a pull request then we can checkout the head. |
|||
fetch-depth: 2 |
|||
|
|||
# If this run was triggered by a pull request event, then checkout |
|||
# the head of the pull request instead of the merge commit. |
|||
- run: git checkout HEAD^2 |
|||
if: ${{ github.event_name == 'pull_request' }} |
|||
|
|||
# Initializes the CodeQL tools for scanning. |
|||
- name: Initialize CodeQL |
|||
uses: github/codeql-action/init@v1 |
|||
with: |
|||
languages: ${{ matrix.language }} |
|||
# If you wish to specify custom queries, you can do so here or in a config file. |
|||
# By default, queries listed here will override any specified in a config file. |
|||
# Prefix the list here with "+" to use these queries and those in the config file. |
|||
# queries: ./path/to/local/query, your-org/your-repo/queries@main |
|||
|
|||
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java). |
|||
# If this step fails, then you should remove it and run the build manually (see below) |
|||
- name: Autobuild |
|||
uses: github/codeql-action/autobuild@v1 |
|||
|
|||
# ℹ️ Command-line programs to run using the OS shell. |
|||
# 📚 https://git.io/JvXDl |
|||
|
|||
# ✏️ If the Autobuild fails above, remove it and uncomment the following three lines |
|||
# and modify them (or add more) to build your code if your project |
|||
# uses a compiled language |
|||
|
|||
#- run: | |
|||
# make bootstrap |
|||
# make release |
|||
|
|||
- name: Perform CodeQL Analysis |
|||
uses: github/codeql-action/analyze@v1 |
|||
@ -0,0 +1,31 @@ |
|||
{ |
|||
"culture": "ar", |
|||
"texts": { |
|||
"Volo.AbpIo.Domain:010004": "تم الوصول إلى الحد الأقصى لعدد الأعضاء!", |
|||
"Volo.AbpIo.Domain:010005": "تم الوصول إلى الحد الأقصى لعدد المالكين!", |
|||
"Volo.AbpIo.Domain:010006": "هذا المستخدم هو بالفعل مالك في هذه المنظمة!", |
|||
"Volo.AbpIo.Domain:010007": "هذا المستخدم هو بالفعل مطور في هذه المنظمة!", |
|||
"Volo.AbpIo.Domain:010008": "لا يمكن أن يكون عدد المطورين المسموح لهم أقل من عدد المطورين الحاليين!", |
|||
"Volo.AbpIo.Domain:010009": "لا يمكن أن يكون عدد المطورين المسموح لهم أقل من 0!", |
|||
"Volo.AbpIo.Domain:010010": "تم تجاوز الحد الأقصى لعدد عناوين mac!", |
|||
"Volo.AbpIo.Domain:010011": "لا يمكن أن تحتوي الرخصة الشخصية على أكثر من مطور واحد!", |
|||
"Volo.AbpIo.Domain:010012": "لا يمكن تمديد الترخيص بعد شهر واحد من انتهاء صلاحية الترخيص!", |
|||
"Volo.AbpIo.Domain:020001": "تعذر حذف حزمة NPM هذه لأن \"{NugetPackages}\" حزم Nuget تعتمد على هذه الحزمة.", |
|||
"Volo.AbpIo.Domain:020002": "تعذر حذف حزمة NPM هذه لأن \"{Modules}\" الوحدات النمطية تستخدم هذه الحزمة.", |
|||
"Volo.AbpIo.Domain:020003": "تعذر حذف حزمة NPM هذه لأن \"{Modules}\" الوحدات النمطية تستخدم هذه الحزمة و \"{NugetPackages}\" حزم Nuget تعتمد على هذه الحزمة.", |
|||
"Volo.AbpIo.Domain:020004": "تعذر حذف حزمة Nuget هذه لأن \"{Modules}\" الوحدات النمطية تستخدم هذه الحزمة.", |
|||
"WantToLearn?": "تريد أن تتعلم؟", |
|||
"ReadyToGetStarted?": "على استعداد للبدء؟", |
|||
"JoinOurCommunity": "انضم إلى مجتمعنا", |
|||
"GetStartedUpper": "دعنا نبدأ", |
|||
"ForkMeOnGitHub": "GitHub أعطنى تنبيه على", |
|||
"Features": "خصائص", |
|||
"GetStarted": "دعنا نبدأ", |
|||
"Documents": "وثائق", |
|||
"Community": "مجتمع", |
|||
"ContributionGuide": "دليل المساهمة", |
|||
"Blog": "المدونة", |
|||
"Commercial": "تجارى", |
|||
"SeeDocuments": "انظر للوثائق" |
|||
} |
|||
} |
|||
@ -0,0 +1,35 @@ |
|||
{ |
|||
"culture": "ar", |
|||
"texts": { |
|||
"OrganizationManagement": "إدارة المنظمة", |
|||
"OrganizationList": "قائمة المنظمات", |
|||
"Volo.AbpIo.Commercial:010003": "لست مالك هذه المنظمة!", |
|||
"OrganizationNotFoundMessage": "لا توجد أى منظمة!", |
|||
"DeveloperCount": "المحجوز / إجمالى المطورين", |
|||
"QuestionCount": "المتبقى / إجمالى الأسئلة", |
|||
"Unlimited": "غير محدود", |
|||
"Owners": "مُلاّك", |
|||
"AddMember": "تسجيل عضو", |
|||
"AddOwner": "تسجيل مالك", |
|||
"AddDeveloper": "تسجيل مطور", |
|||
"UserName": "اسم المستخدم", |
|||
"Name": "الاسم", |
|||
"EmailAddress": "البريد الإلكترونى", |
|||
"Developers": "مطورون", |
|||
"LicenseType": "نوع الرخصة", |
|||
"Manage": "إدارة", |
|||
"StartDate": "تاريخ البداية", |
|||
"EndDate": "تاريخ الإنتهاء", |
|||
"Modules": "Modules", |
|||
"LicenseExtendMessage": "تم تمديد تاريخ انتهاء الترخيص الخاص بك إلى {0}", |
|||
"LicenseUpgradeMessage": "تمت ترقية ترخيصك إلى {0}", |
|||
"LicenseAddDeveloperMessage": "تمت إضافة {0} من المطورين إلى ترخيصك", |
|||
"Volo.AbpIo.Commercial:010004": "لا يمكن العثور على المستخدم المحدد! يجب أن يكون المستخدم قد سجل بالفعل.", |
|||
"MyOrganizations": "منظماتى", |
|||
"ApiKey": "مفتاح API", |
|||
"UserNameNotFound": "لا يوجد مستخدم باسم {0}", |
|||
"SuccessfullyAddedToNewsletter": "شكرا لك على الاشتراك في النشرة الإخبارية لدينا!", |
|||
"MyProfile": "ملفي", |
|||
"EmailNotValid": "من فضلك أدخل بريد أليكترونى صحيح." |
|||
} |
|||
} |
|||
@ -0,0 +1,68 @@ |
|||
{ |
|||
"culture": "ar", |
|||
"texts": { |
|||
"Permission:CommunityArticle": "مقالة المجتمع", |
|||
"Permission:Edit": "تعديل", |
|||
"Waiting": "انتظار", |
|||
"Approved": "تمت الموافقة", |
|||
"Rejected": "مرفوض", |
|||
"Wait": "انتظر", |
|||
"Approve": "موافق", |
|||
"Reject": "رفض", |
|||
"ReadArticle": "إقرأ المقال", |
|||
"Status": "الحالة", |
|||
"ContentSource": "مصدر المحتوى", |
|||
"Details": "التفاصيل", |
|||
"Url": "عنوان الموقع", |
|||
"Title": "العنوان", |
|||
"CreationTime": "وقت الإنشاء", |
|||
"Save": "حفظ", |
|||
"SameUrlAlreadyExist": "نفس عنوان الموقع موجود بالفعل إذا كنت تريد إضافة هذه المقالة ، يجب عليك تغيير عنوانها!", |
|||
"UrlIsNotValid": "عنوان الموقع غير صحيح.", |
|||
"UrlNotFound": "عنوان الموقع غير موجود.", |
|||
"UrlContentNotFound": "محتوى الموقع غير موجود.", |
|||
"Summary": "الخلاصة", |
|||
"MostRead": "الأكثر قراءة", |
|||
"Latest": "آخر", |
|||
"ContributeAbpCommunity": "المساهمة في مجتمع ABP", |
|||
"SubmitYourArticle": "إرسال مقالتك", |
|||
"ContributionGuide": "دليل المساهمة", |
|||
"BugReport": "الإبلاغ عن خطأ", |
|||
"SeeAllArticles": "انظر جميع المقالات", |
|||
"WelcomeToABPCommunity!": "مرحبًا بك في مجتمع ABP!", |
|||
"MyProfile": "ملفى", |
|||
"MyOrganizations": "منظماتي", |
|||
"EmailNotValid": "من فضلك أدخل بريد أليكترونى صحيح.", |
|||
"FeatureRequest": "طلب خاصية جديدة", |
|||
"CreateArticleTitleInfo": "عنوان المقال الذي سيظهر في قائمة المقالات.", |
|||
"CreateArticleUrlInfo": "الأصل GitHub / عنوان URL خارجي للمقالة.", |
|||
"CreateArticleSummaryInfo": "ملخص قصير للمقال ليتم عرضه في قائمة المقالات.", |
|||
"CreateArticleCoverInfo": "لإنشاء مقال فعال ، أضف صورة غلاف. لن يتم قبول سوى صور بنسبة عرض إلى ارتفاع تبلغ 9:16!", |
|||
"ThisExtensionIsNotAllowed": "امتداد الملف غير مسموح.", |
|||
"TheFileIsTooLarge": "مسار الملف طويل جداً", |
|||
"GoToTheArticle": "الذهاب للمقال", |
|||
"Contribute": "ساهم", |
|||
"OverallProgress": "التقدم الكلى", |
|||
"Done": "تم", |
|||
"Open": "افتح", |
|||
"Closed": "أُغلق", |
|||
"LatestQuestionOnThe": "آخر سؤال فى", |
|||
"Stackoverflow": "Stackoverflow", |
|||
"Votes": "تصويتات", |
|||
"Answer": "إجابة", |
|||
"Views": "مشاهدة", |
|||
"Answered": "تمت الإجابة عنه", |
|||
"WaitingForYourAnswer": "بانتظار إجابتك", |
|||
"Asked": "تم السؤال", |
|||
"AllQuestions": "كل الأسئلة", |
|||
"NextVersion": "الإصدار القادم", |
|||
"MilestoneErrorMessage": "تعذر الحصول على تفاصيل المعالم الحالية من Github.", |
|||
"QuestionItemErrorMessage": "تعذر الحصول على أحدث تفاصيل السؤال من Stackoverflow.", |
|||
"Oops": "عفواً!", |
|||
"CreateArticleSuccessMessage": "تم تقديم المقال بنجاح. سيتم نشره بعد مراجعة من إدارة الموقع.", |
|||
"ChooseCoverImage": "اختر صورة الغلاف...", |
|||
"CoverImage": "صورة الغلاف", |
|||
"ShareYourExperiencesWithTheABPFramework": "شارك خبراتك مع إطار عمل برنامج ABP!", |
|||
"Optional": "اختيارى" |
|||
} |
|||
} |
|||
@ -0,0 +1,161 @@ |
|||
{ |
|||
"culture": "ar", |
|||
"texts": { |
|||
"GetStarted": "ابدأ - قوالب بدء التشغيل", |
|||
"Create": "إنشاء", |
|||
"NewProject": "مشروع جديد", |
|||
"DirectDownload": "تحميل مباشر", |
|||
"ProjectName": "اسم المشروع", |
|||
"ProjectType": "نوع المشروع", |
|||
"DatabaseProvider": "مزود قاعدة البيانات", |
|||
"NTier": "N- الطبقة", |
|||
"IncludeUserInterface": "تشمل واجهة المستخدم", |
|||
"CreateNow": "إنشاء جديد", |
|||
"TheStartupProject": "مشروع بدء التشغيل", |
|||
"Tutorial": "الدورة التعليمية", |
|||
"UsingCLI": "باستخدام CLI", |
|||
"SeeDetails": "انظر التفاصيل", |
|||
"AbpShortDescription": "ABP Framework بنية أساسية كاملة لإنشاء تطبيقات ويب حديثة باتباع أفضل ممارسات واتفاقيات تطوير البرامج.", |
|||
"SourceCodeUpper": "شفرة المصدر", |
|||
"LatestReleaseLogs": "أحدث سجلات الإصدار", |
|||
"Infrastructure": "البنية التحتية", |
|||
"Architecture": "الهيكلة", |
|||
"Modular": "معياري", |
|||
"DontRepeatYourself": "لا تكرر نفسك", |
|||
"DeveloperFocused": "تركيز المطور", |
|||
"FullStackApplicationInfrastructure": "البنية التحتية الكاملة للتطبيق.", |
|||
"DomainDrivenDesign": "Domain Driven Design", |
|||
"DomainDrivenDesignExplanation": "تم تصميمه وتطويره بناءً على أنماط ومبادئ DDD. يوفر نموذجًا متعدد الطبقات لتطبيقك.", |
|||
"Authorization": "تفويض", |
|||
"AuthorizationExplanation": "إذن متقدم مع نظام أذونات مستخدم ودور ودقيق. مبني على مكتبة هوية Microsoft.", |
|||
"MultiTenancy": "متعدد الايجار", |
|||
"MultiTenancyExplanationShort": "جعلت تطبيقات SaaS سهلة! متعدد الإيجارات المتكاملة من قاعدة البيانات إلى واجهة المستخدم.", |
|||
"CrossCuttingConcerns": "اهتمامات مشتركة", |
|||
"CrossCuttingConcernsExplanationShort": "بنية تحتية كاملة للتفويض والتحقق من الصحة ومعالجة الاستثناءات والتخزين المؤقت وتسجيل التدقيق وإدارة المعاملات والمزيد.", |
|||
"BuiltInBundlingMinification": "تجميع وتصغير مدمج", |
|||
"BuiltInBundlingMinificationExplanation": "لا حاجة لاستخدام أدوات خارجية للتجميع والتصغير. تقدم ABP طريقة أبسط وديناميكية وقوية ومتكاملة ومدمجة!", |
|||
"VirtualFileSystem": "نظام الملفات الافتراضي", |
|||
"VirtualFileSystemExplanation": "قم بتضمين العروض والنصوص والأنماط والصور ... في الحزم / المكتبات وإعادة استخدامها في تطبيقات مختلفة.", |
|||
"Theming": "تصميم", |
|||
"ThemingExplanationShort": "استخدم وتخصيص سمة واجهة المستخدم القياسية القائمة على التمهيد أو قم بإنشاء سمة خاصة بك.", |
|||
"BootstrapTagHelpersDynamicForms": "أدوات مساعدة علامة التمهيد والنماذج الديناميكية", |
|||
"BootstrapTagHelpersDynamicFormsExplanation": "بدلاً من كتابة التفاصيل المتكررة لمكونات التمهيد يدويًا ، استخدم مساعدي علامات ABP لتبسيطها والاستفادة من التحسس. أنشئ نماذج واجهة مستخدم بسرعة استنادًا إلى نموذج C # باستخدام مساعد علامة النموذج الديناميكي.", |
|||
"HTTPAPIsDynamicProxies": "HTTP APIs & Dynamic Proxies", |
|||
"HTTPAPIsDynamicProxiesExplanation": "كشف خدمات التطبيقات تلقائيًا على أنها واجهات برمجة تطبيقات HTTP بنمط REST ، واستهلكها باستخدام وكلاء JavaScript و C # الديناميكيين.", |
|||
"CompleteArchitectureInfo": "هندسة معمارية حديثة لإنشاء حلول برمجية قابلة للصيانة.", |
|||
"DomainDrivenDesignBasedLayeringModelExplanation": "يساعدك على تنفيذ بنية طبقات تستند إلى DDD وبناء قاعدة رمز قابلة للصيانة.", |
|||
"DomainDrivenDesignBasedLayeringModelExplanationCont": "يوفر قوالب بدء التشغيل ، والملخصات ، والفئات الأساسية ، والخدمات ، والوثائق والأدلة لمساعدتك على تطوير تطبيقك بناءً على أنماط ومبادئ DDD.", |
|||
"MicroserviceCompatibleModelExplanation": "تم تصميم إطار العمل الأساسي ووحدات ما قبل الإنشاء مع مراعاة بنية الخدمات المصغرة.", |
|||
"MicroserviceCompatibleModelExplanationCont": "يوفر البنية التحتية وعمليات الدمج والعينات والوثائق لتنفيذ حلول الخدمات المصغرة بشكل أسهل ، في حين أنه لا يجلب تعقيدًا إضافيًا إذا كنت تريد تطبيقًا مترابطًا.", |
|||
"ModularInfo": "يوفر ABP نظام وحدة نمطية يسمح لك بتطوير وحدات تطبيق قابلة لإعادة الاستخدام ، والربط بأحداث دورة حياة التطبيق ، والتعبير عن التبعيات بين الأجزاء الأساسية في نظامك.", |
|||
"PreBuiltModulesThemes": "الوحدات والسمات المبنية مسبقًا", |
|||
"PreBuiltModulesThemesExplanation": "الوحدات والسمات مفتوحة المصدر والتجارية جاهزة للاستخدام في تطبيق عملك.", |
|||
"NuGetNPMPackages": "حزم NuGet و NPM", |
|||
"NuGetNPMPackagesExplanation": "توزع كحزم NuGet و NPM. سهل التركيب والترقية.", |
|||
"ExtensibleReplaceable": "قابل للتوسيع / قابل للاستبدال", |
|||
"ExtensibleReplaceableExplanation": "تم تصميم جميع الخدمات والوحدات النمطية في الاعتبار قابلية التوسع. يمكنك استبدال الخدمات والصفحات والأنماط والمكونات.", |
|||
"CrossCuttingConcernsExplanation2": "اجعل قاعدة الشفرة أصغر حتى تتمكن من التركيز على الكود الخاص بنشاطك التجاري.", |
|||
"CrossCuttingConcernsExplanation3": "لا ترسل وقتًا لتنفيذ متطلبات التطبيق المشتركة في مشاريع متعددة.", |
|||
"AuthenticationAuthorization": "المصادقة والتفويض", |
|||
"ExceptionHandling": "معالجة الاستثناء", |
|||
"Validation": "التحقق من الصحة", |
|||
"DatabaseConnection": "اتصال قاعدة البيانات", |
|||
"TransactionManagement": "إدارة المعاملات", |
|||
"AuditLogging": "تدوين التسجيل", |
|||
"Caching": "التخزين المؤقت", |
|||
"Multitenancy": "التعددية", |
|||
"DataFiltering": "تصفية البيانات", |
|||
"ConventionOverConfiguration": "اتفاقية على التكوين", |
|||
"ConventionOverConfigurationExplanation": "تنفذ ABP اصطلاحات التطبيق الشائعة افتراضيًا باستخدام الحد الأدنى من التكوين أو صفر.", |
|||
"ConventionOverConfigurationExplanationList1": "التسجيل التلقائى للخدمات المعروفة بحقن التبعية.", |
|||
"ConventionOverConfigurationExplanationList2": "يعرض خدمات التطبيقات على أنها واجهات برمجة تطبيقات HTTP من خلال اصطلاحات التسمية.", |
|||
"ConventionOverConfigurationExplanationList3": "يقوم بإنشاء وكلاء عميل HTTP ديناميكي لـ C # و JavaScript.", |
|||
"ConventionOverConfigurationExplanationList4": "يوفر المستودعات الافتراضية للكيانات الخاصة بك.", |
|||
"ConventionOverConfigurationExplanationList5": "إدارة وحدة العمل حسب طلب الويب أو طريقة خدمة التطبيق.", |
|||
"ConventionOverConfigurationExplanationList6": "ينشر إنشاء وتحديث وحذف الأحداث للكيانات الخاصة بك.", |
|||
"BaseClasses": "الفئات الأساسية", |
|||
"BaseClassesExplanation": "فئات أساسية مسبقة الصنع لأنماط التطبيق الشائعة.", |
|||
"DeveloperFocusedExplanation": "ABP للمطورين.", |
|||
"DeveloperFocusedExplanationCont": "يهدف إلى تبسيط عملية تطوير البرامج اليومية مع عدم تقييدك من كتابة رمز منخفض المستوى.", |
|||
"SeeAllFeatures": "انظر جميع الميزات", |
|||
"CLI_CommandLineInterface": "CLI (واجهة سطر الأوامر)", |
|||
"CLI_CommandLineInterfaceExplanation": "يتضمن CLI لمساعدتك على أتمتة إنشاء مشاريع جديدة وإضافة وحدات نمطية جديدة.", |
|||
"StartupTemplates": "قوالب بدء التشغيل", |
|||
"StartupTemplatesExplanation": "توفر قوالب بدء التشغيل المختلفة حلاً مهيئًا بالكامل لبدء التطوير السريع.", |
|||
"BasedOnFamiliarTools": "بناءاً على أدوات معروفة", |
|||
"BasedOnFamiliarToolsExplanation": "مصمم ومتكامل مع الأدوات الشائعة التي تعرفها بالفعل. منحنى تعليمي منخفض ، سهل التكيف ، تنمية مريحة.", |
|||
"ORMIndependent": "ORM مستقل", |
|||
"ORMIndependentExplanation": "الإطار الأساسي هو ORM / قاعدة البيانات مستقل ويمكن أن يعمل مع أي مصدر بيانات. يتوفر مقدمو Entity Framework Core و MongoDB بالفعل.", |
|||
"Features": "استكشف ميزات إطار عمل ABP", |
|||
"ABPCLI": "ABP CLI", |
|||
"Modularity": "النمطية", |
|||
"BootstrapTagHelpers": "مساعدي علامة التمهيد", |
|||
"DynamicForms": "شاشات ديناميكية", |
|||
"BundlingMinification": "التجميع والتصغير", |
|||
"BackgroundJobs": "وظائف الخلفية", |
|||
"DDDInfrastructure": "البنية التحتية DDD", |
|||
"DomainDrivenDesignInfrastructure": "البنية التحتية للتصميم يحركها المجال", |
|||
"AutoRESTAPIs": "واجهات برمجة تطبيقات Auto REST", |
|||
"DynamicClientProxies": "وكلاء العميل الديناميكي", |
|||
"DistributedEventBus": "حافلة الحدث الموزعة", |
|||
"DistributedEventBusWithRabbitMQIntegration": "حافلة الحدث الموزعة مع تكامل RabbitMQ", |
|||
"TestInfrastructure": "اختبار البنية التحتية", |
|||
"AuditLoggingEntityHistories": "سجل التدقيق وتاريخ الكيان", |
|||
"ObjectToObjectMapping": "مطابقة كائن إلى كائن", |
|||
"EmailSMSAbstractions": "التجريد من البريد الإلكتروني والرسائل النصية القصيرة", |
|||
"EmailSMSAbstractionsWithTemplatingSupport": "تجريدات البريد الإلكتروني والرسائل النصية القصيرة مع دعم القوالب", |
|||
"Localization": "التعريب", |
|||
"SettingManagement": "إدارة الإعدادات", |
|||
"ExtensionMethods": "طرق التمديد", |
|||
"ExtensionMethodsHelpers": "طرق التمديد والمساعدين", |
|||
"AspectOrientedProgramming": "البرمجة الموجهة", |
|||
"DependencyInjection": "حقن التبعية", |
|||
"DependencyInjectionByConventions": "حقن التبعية بالاتفاقيات", |
|||
"ABPCLIExplanation": "ABP CLI (واجهة سطر الأوامر) هي أداة سطر أوامر لإجراء بعض العمليات الشائعة للحلول المستندة إلى ABP.", |
|||
"ModularityExplanation": "يوفر ABP بنية أساسية كاملة لبناء وحدات التطبيق الخاصة بك والتي قد تحتوي على كيانات وخدمات وتكامل قواعد البيانات وواجهات برمجة التطبيقات ومكونات واجهة المستخدم وما إلى ذلك ..", |
|||
"MultiTenancyExplanation": "لا يدعم إطار عمل ABP تطوير التطبيقات متعددة المستأجرين فحسب ، بل يجعل الكود الخاص بك في الغالب غير مدرك للتعددية المستأجرة.", |
|||
"MultiTenancyExplanation2": "يمكن تحديد المستأجر الحالي تلقائيًا ، وعزل بيانات المستأجرين المختلفين عن بعضهم البعض.", |
|||
"MultiTenancyExplanation3": "يدعم قاعدة بيانات واحدة وقاعدة بيانات لكل مستأجر ونهج مختلطة.", |
|||
"MultiTenancyExplanation4": "أنت تركز على رمز عملك وتدع إطار العمل للتعامل مع عقود الإيجار المتعددة نيابة عنك.", |
|||
"BootstrapTagHelpersExplanation": "بدلاً من كتابة التفاصيل المتكررة لمكونات التمهيد يدويًا ، استخدم مساعدي علامات ABP لتبسيطها والاستفادة من التحسس. يمكنك بالتأكيد استخدام Bootstrap متى احتجت إليه.", |
|||
"DynamicFormsExplanation": "يمكن لمساعدي النموذج الديناميكي وعلامات الإدخال إنشاء النموذج الكامل من فئة C # كنموذج.", |
|||
"AuthenticationAuthorizationExplanation": "خيارات المصادقة والترخيص الغنية المدمجة في ASP.NET Core Identity & IdentityServer4. يوفر نظام إذن موسع ومفصل.", |
|||
"CrossCuttingConcernsExplanation": "لا تكرر نفسك لتنفيذ كل هذه الأشياء الشائعة مرارًا وتكرارًا. ركز على رمز عملك ودع برنامج ABP يقوم بأتمتة ذلك من خلال الاتفاقيات.", |
|||
"DatabaseConnectionTransactionManagement": "اتصال قاعدة البيانات وإدارة المعاملات", |
|||
"CorrelationIdTracking": "تتبع معرف الارتباط", |
|||
"BundlingMinificationExplanation": "تقدم ABP نظام تجميع وتقليل بسيط وديناميكي وقوي ونمطي ومدمج.", |
|||
"VirtualFileSystemnExplanation": "يتيح نظام الملفات الظاهري إدارة الملفات غير الموجودة فعليًا على نظام الملفات (القرص). يتم استخدامه بشكل أساسي لتضمين ملفات (js ، css ، image ، cshtml ...) في التجميعات واستخدامها مثل الملفات الفعلية في وقت التشغيل.", |
|||
"ThemingExplanation": "يسمح نظام Theming بتطوير سمة التطبيق والوحدات النمطية الخاصة بك بشكل مستقل عن طريق تحديد مجموعة من المكتبات الأساسية المشتركة والتخطيطات ، بناءً على أحدث إطار عمل Bootstrap.", |
|||
"DomainDrivenDesignInfrastructureExplanation": "بنية تحتية كاملة لإنشاء تطبيقات متعددة الطبقات بناءً على أنماط ومبادئ التصميم المدفوع بالمجال ؛", |
|||
"Specification": "تخصيص", |
|||
"Repository": "مخزن", |
|||
"DomainService": "خدمة المجال", |
|||
"ValueObject": "كائن القيمة", |
|||
"ApplicationService": "خدمة التطبيق", |
|||
"DataTransferObject": "كائن نقل البيانات", |
|||
"AggregateRootEntity": "تجميع الجذر والكيان", |
|||
"AutoRESTAPIsExplanation": "يمكن لـ ABP تكوين خدمات التطبيقات الخاصة بك تلقائيًا كوحدات تحكم API حسب الاصطلاح.", |
|||
"DynamicClientProxiesExplanation": "استهلك واجهات برمجة التطبيقات الخاصة بك بسهولة من عملاء JavaScript و C#.", |
|||
"DistributedEventBusWithRabbitMQIntegrationExplanation": "انشر واستهلك الأحداث الموزعة بسهولة باستخدام ناقل الأحداث الموزع المدمج مع توفر تكامل RabbitMQ.", |
|||
"TestInfrastructureExplanation": "تم تطوير إطار العمل واختبار الوحدة والتكامل في الاعتبار. يوفر لك الفئات الأساسية لتسهيل الأمر. تأتي قوالب بدء التشغيل مع تكوين مسبق للاختبار.", |
|||
"AuditLoggingEntityHistoriesExplanation": "تسجيل تدقيق مدمج للتطبيقات المهمة للأعمال. الطلب والخدمة وتسجيل التدقيق على مستوى الطريقة وتاريخ الكيان مع تفاصيل مستوى الملكية.", |
|||
"EmailSMSAbstractionsWithTemplatingSupportExplanation": "تفصل تجريدات IEmailSender و ISmsSender منطق التطبيق الخاص بك عن البنية التحتية. يسمح نظام قوالب البريد الإلكتروني المتقدم بإنشاء قوالب البريد الإلكتروني وتعريبها واستخدامها بسهولة عند الحاجة.", |
|||
"LocalizationExplanation": "يسمح نظام التعريب بإنشاء موارد في ملفات JSON عادية واستخدامها لتعريب واجهة المستخدم الخاصة بك. وهو يدعم السيناريوهات المتقدمة مثل الوراثة والإضافات وتكامل JavaScript بينما يتوافق تمامًا مع نظام توطين AspNet Core.", |
|||
"SettingManagementExplanation": "حدد إعدادات التطبيق الخاص بك واحصل على القيم في وقت التشغيل بناءً على التكوين الحالي والمستأجر والمستخدم.", |
|||
"ExtensionMethodsHelpersExplanation": "لا تكرر نفسك حتى مع أجزاء التعليمات البرمجية البسيطة. الإضافات والمساعدات للأنواع القياسية تجعل التعليمات البرمجية أكثر وضوحًا وسهولة في الكتابة.", |
|||
"AspectOrientedProgrammingExplanation": "يوفر بنية تحتية مريحة لإنشاء وكلاء ديناميكيين وتنفيذ البرمجة الموجهة نحو الجانب. اعترض أي فئة وقم بتنفيذ التعليمات البرمجية الخاصة بك قبل وبعد تنفيذ كل طريقة.", |
|||
"DependencyInjectionByConventionsExplanation": "لا حاجة لتسجيل فصولك في حقن التبعية يدويًا. يسجل تلقائيًا أنواع الخدمات الشائعة حسب الاصطلاح. بالنسبة لأنواع الخدمات الأخرى ، يمكنك استخدام الواجهات والسمات لتسهيل الأمر ووضعه في مكانه.", |
|||
"DataFilteringExplanation": "تحديد واستخدام عوامل تصفية البيانات التي يتم تطبيقها تلقائيًا عند الاستعلام عن الكيانات من قاعدة البيانات. يتم توفير مرشحات Soft Delete & MultiTenant خارج الصندوق عند تنفيذ واجهات بسيطة.", |
|||
"PublishEvents": "نشر الأحداث", |
|||
"HandleEvents": "معالجة الأحداث", |
|||
"AndMore": "وأكثر من ذلك ...", |
|||
"Code": "شفرة", |
|||
"Result": "النتيجة", |
|||
"SeeTheDocumentForMoreInformation": "راجع الـ <a href=\"{1}\">{0} الوثيقة</a> لمزيد من المعلومات", |
|||
"IndexPageHeroSection": "<span class=\"first-line shine\"><strong>فتح المصدر</strong></span><span class=\"second-line text-uppercase\">تطبيق الويب<br />إطار </span><span class=\"third-line shine2\"><strong>لـ asp.net core</strong></span>", |
|||
"UiFramework": "إطار عمل واجهة المستخدم", |
|||
"EmailAddress": "البريد الإلكترونى", |
|||
"Mobile": "المحمول", |
|||
"ReactNative": "React Native" |
|||
} |
|||
} |
|||
@ -0,0 +1,15 @@ |
|||
{ |
|||
"grammarly.userWords": [ |
|||
"api", |
|||
"apiName", |
|||
"cli", |
|||
"defaultProject", |
|||
"formatter", |
|||
"md", |
|||
"monorepo", |
|||
"ngsw", |
|||
"npx", |
|||
"pwa", |
|||
"rootNamespace" |
|||
] |
|||
} |
|||
@ -0,0 +1,262 @@ |
|||
# ABP Framework & ABP Commercial 3.2 RC With The New Blazor UI |
|||
|
|||
We are extremely excited today to release the [ABP Framework](https://abp.io/) Release Candidate (and the [ABP Commercial](https://commercial.abp.io/), as always). This release includes an early preview version of the **Blazor UI** for the ABP.IO Platform. |
|||
|
|||
## The Blazor UI |
|||
|
|||
While the Blazor UI **should be considered as experimental** for now, it is possible to start to develop your application today. |
|||
|
|||
### Fundamental Services |
|||
|
|||
Currently, implemented some important framework features; |
|||
|
|||
* **Authentication** through the MVC backend using the OpenId Connect authorization code flow. So, all the current login options (login, register, forgot password, external/social logins...) are supported. |
|||
* **Authorization**, using the ABP Framework **permissions** as well as the standard authorization system. |
|||
* **Localization** just works like the MVC UI. |
|||
* **Basic Theme** with top main menu. |
|||
* **Dynamic C# HTTP API proxies**, so you can directly consume your backend API by injecting the application service interfaces. |
|||
* Some other **fundamental services** like `ISettingProvider`, `IFeatureChecker`, `ICurrentUser`... |
|||
|
|||
Also, the standard .net services are already available, like caching, logging, validation and much more. Since the ABP Framework is layered itself, all the non MVC UI related features are already usable for the Blazor UI. |
|||
|
|||
### Pre-Built Modules |
|||
|
|||
Some modules have been implemented; |
|||
|
|||
* **Identity** module is pre-installed and provides **user, role and permission management**. |
|||
* **Profile management** page is implemented to allow to change password and personal settings. |
|||
|
|||
### About the Blazorise Library |
|||
|
|||
We've selected the [Blazorise](https://blazorise.com/) as a fundamental UI library for the Blazor UI. It already supports different HTML/CSS frameworks (like Bootstrap, Bulma, Ant Design...) and significantly increases the developer productivity. |
|||
|
|||
 |
|||
|
|||
We also have a good news: **[Mladen Macanović](https://github.com/stsrki)**, the creator of the Blazorise, is **joining to the core ABP Framework team** in the next weeks. We are excited to work with him to bring the power of these two successful projects together. |
|||
|
|||
### The Tutorial |
|||
|
|||
We've **updated** the [web application development tutorial](https://docs.abp.io/en/abp/3.2/Tutorials/Part-1?UI=Blazor) for the **Blazor UI**. You can start to develop applications today! The **source code** of the BookStore application developed with this tutorial is [here](https://github.com/abpframework/abp-samples/tree/master/BookStore-Blazor-EfCore). |
|||
|
|||
### Get started with the Blazor UI |
|||
|
|||
If you want to try the Blazor UI today, follow the instructions below. |
|||
|
|||
#### Upgrade the ABP CLI |
|||
|
|||
Install the latest [ABP CLI](https://docs.abp.io/en/abp/3.2/CLI) preview version: |
|||
|
|||
````bash |
|||
dotnet tool update Volo.Abp.Cli -g --version 3.2.0-rc.2 |
|||
```` |
|||
|
|||
#### Create a new Solution |
|||
|
|||
Then you can create a new solution using the *abp new* command: |
|||
|
|||
````bash |
|||
abp new AbpBlazorDemo -u blazor --preview |
|||
```` |
|||
|
|||
Also specify the `-t app-pro` parameter if you are an ABP Commercial user. |
|||
|
|||
> See the ABP CLI documentation for the additional options, like MongoDB database or separated authentication server. |
|||
|
|||
#### Open the Solution |
|||
|
|||
Open the generated solution using the latest Visual Studio 2019. You will see a solution structure like the picture below: |
|||
|
|||
 |
|||
|
|||
#### Run the Application |
|||
|
|||
* Run the `DbMigrator` project to create the database and seed the initial data. |
|||
* Run the `HttpApi.Host` project for the server side. |
|||
* Run the `Blazor` project to start the Blazor UI. |
|||
|
|||
Use `admin` as the username and `1q2w3E*` as the password to login to the application. |
|||
|
|||
Here, a screenshot from the role management page of the Blazor UI: |
|||
|
|||
 |
|||
|
|||
## What's New with the ABP Framework 3.2 |
|||
|
|||
Beside the Blazor UI, there are a lot of issues have been closed with [the milestone 3.2](https://github.com/abpframework/abp/milestone/39?closed=1). I will highlight some of the major features and changes released with this version. |
|||
|
|||
### MongoDB ACID Transactions |
|||
|
|||
[MongoDB integration](https://docs.abp.io/en/abp/3.2/MongoDB) now supports multi-document transactions that comes with the MongoDB 4.x. |
|||
|
|||
We've **disabled transactions** for solutions use the MongoDB, inside the `YourProjectMongoDbModule.cs` file in the MongoDB project. If your MongoDB server **supports transactions**, you should manually enable it in this class: |
|||
|
|||
```csharp |
|||
Configure<AbpUnitOfWorkDefaultOptions>(options => |
|||
{ |
|||
options.TransactionBehavior = UnitOfWorkTransactionBehavior.Auto; |
|||
}); |
|||
``` |
|||
|
|||
> Or you can delete this code since this is already the default behavior. |
|||
|
|||
#### Upgrade Notes |
|||
|
|||
If you are upgrading an existing solution and your MongoDB server doesn't support transactions, please disable it: |
|||
|
|||
```csharp |
|||
Configure<AbpUnitOfWorkDefaultOptions>(options => |
|||
{ |
|||
options.TransactionBehavior = UnitOfWorkTransactionBehavior.Disabled; |
|||
}); |
|||
``` |
|||
|
|||
See the [Unit Of Work document](https://docs.abp.io/en/abp/3.2/Unit-Of-Work) to learn more about UOW and transactions. |
|||
|
|||
Also, add [this file](https://github.com/abpframework/abp/blob/rel-3.2/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.MongoDB/MongoDb/MongoDbMyProjectNameDbSchemaMigrator.cs) into your MongoDB project (remember to change `MongoDbMyProjectNameDbSchemaMigrator` and `IMyProjectNameDbSchemaMigrator` with your own project name). |
|||
|
|||
#### Integration Tests |
|||
|
|||
> Transactions are also **disabled for automated integration tests** coming with the application startup template, since the [Mongo2Go](https://github.com/Mongo2Go/Mongo2Go) library (we use in the test projects) has a problem with the transactions. We've sent a [Pull Request](https://github.com/Mongo2Go/Mongo2Go/pull/101) to fix it and will enable the transactions again when they merge & release it. |
|||
> |
|||
> If you are upgrading an existing solution and using MongoDB, please disable transactions for the test projects just as described above. |
|||
|
|||
### Kafka Integration for the Distributed Event Bus |
|||
|
|||
ABP Framework's [distributed event system](https://docs.abp.io/en/abp/3.2/Distributed-Event-Bus) has been [integrated to RabbitMQ](https://docs.abp.io/en/abp/3.2/Distributed-Event-Bus-RabbitMQ-Integration) before. By the version 3.2, it has a Kafka integration package, named [Volo.Abp.EventBus.Kafka](https://www.nuget.org/packages/Volo.Abp.EventBus.Kafka). |
|||
|
|||
See the [Kafka integration documentation](https://docs.abp.io/en/abp/3.2/Distributed-Event-Bus-Kafka-Integration) to learn how to install and configure it. |
|||
|
|||
### Host Features |
|||
|
|||
[ABP Feature System](https://docs.abp.io/en/abp/3.2/Features) allows you to define features in your application. Then you can enable/disable a feature dynamically on the runtime. It is generally used in a [multi-tenant](https://docs.abp.io/en/abp/3.2/Multi-Tenancy) system to restrict features for tenants, so you can charge extra money for some features in a SaaS application. |
|||
|
|||
In some cases, you may want to use the same features in the host side (host is you as you are managing the tenants). For this case, we've added a "**Manage Host Features**" button to the Tenant Management page so you can open a modal dialog to select the features for the host side. |
|||
|
|||
 |
|||
|
|||
### AbpHttpClientBuilderOptions |
|||
|
|||
ABP Framework provides a system to dynamically create C# proxies to consume HTTP APIs from your client applications. `AbpHttpClientBuilderOptions` is a new option class to configure the `HttpClient`s used by the proxy system. |
|||
|
|||
**Example: Use the [Polly](https://github.com/App-vNext/Polly) library to retry up to 3 times for a failed HTTP request** |
|||
|
|||
````csharp |
|||
public override void PreConfigureServices(ServiceConfigurationContext context) |
|||
{ |
|||
PreConfigure<AbpHttpClientBuilderOptions>(options => |
|||
{ |
|||
options.ProxyClientBuildActions.Add((remoteServiceName, clientBuilder) => |
|||
{ |
|||
clientBuilder.AddTransientHttpErrorPolicy(policyBuilder => |
|||
policyBuilder.WaitAndRetryAsync( |
|||
3, |
|||
i => TimeSpan.FromSeconds(Math.Pow(2, i)) |
|||
) |
|||
); |
|||
}); |
|||
}); |
|||
} |
|||
```` |
|||
|
|||
See the issue [#5304](https://github.com/abpframework/abp/issues/5304) for the details. |
|||
|
|||
### ABP Build Command |
|||
|
|||
We are using **mono repository** approach and the [abp repository](https://github.com/abpframework/abp) has tens of solutions and hundreds of projects (the framework, modules, tooling, templates...) with all of them are referencing to each other. |
|||
|
|||
It gets a significant time to build the whole repository for every Git push. To **optimize** this process, we've created the **abp build** command in the [ABP CLI](https://docs.abp.io/en/abp/3.2/CLI): |
|||
|
|||
````bash |
|||
abp build |
|||
```` |
|||
|
|||
We will use this command to build the abp repository or a solution inside it. However it is available to everyone in case of need. |
|||
|
|||
> **Most of the people will not need it**. If you need it, see the [ABP CLI](https://docs.abp.io/en/abp/3.2/CLI) document to learn all the details and options. |
|||
|
|||
### Other Features, Improvements and Changes |
|||
|
|||
* Introduced the `DynamicRangeAttribute` that can be used to determine the range values on runtime, just like the `DynamicStringLengthAttribute` was introduced before. |
|||
* Improved the feature management modal for multi-tenant applications to group features on the UI and show hierarchically. |
|||
* Added `--skip-cli-version-check` option to ABP CLI to improve the performance by bypassing the online version check. |
|||
* Angular UI now redirect to MVC UI (the authentication server side) for profile management page, if the authorization code flow is used (which is the default). |
|||
* Account module profile management page is now extensible. You can implement the `IProfileManagementPageContributor` interface and register it using the `ProfileManagementPageOptions` class. |
|||
* Improvements and optimizations for the [Angular service proxy generation](https://blog.abp.io/abp/Introducing-the-Angular-Service-Proxy-Generation). |
|||
|
|||
And a lot of minor improvements and bug fixes. You can see [the milestone 3.2](https://github.com/abpframework/abp/milestone/39?closed=1) for all issues & PRs closed with this version. |
|||
|
|||
## What's New with the ABP Commercial 3.2 |
|||
|
|||
### Breaking Changes |
|||
|
|||
The new *profile picture management* feature uses the [BLOB storing](https://docs.abp.io/en/abp/3.2/Blob-Storing) system, so it needs a Storage Provider. The new **startup template comes with the [Database BLOB Provider](https://docs.abp.io/en/abp/3.2/Blob-Storing-Database) pre-installed**. You can change it if you want to use another BLOB provider (like Azure, AWS or a simple file system). |
|||
|
|||
**Existing solutions must configure a BLOB provider** after upgrading to the version 3.2. Follow the [BLOB Storing document](https://docs.abp.io/en/abp/3.2/Blob-Storing#blob-storage-providers) to configure the provider yourself. |
|||
|
|||
### The Blazor UI |
|||
|
|||
The **experimental** Blazor UI is also available for the ABP Commercial. The [Lepton Theme](https://commercial.abp.io/themes) hasn't been implemented with this initial preview, however we are working on it with the highest priority. |
|||
|
|||
You can use the [ABP Suite](https://docs.abp.io/en/commercial/latest/abp-suite/index) or the following ABP CLI command to create a new solution with the Blazor UI: |
|||
|
|||
````bash |
|||
abp new AbpBlazorDemo -u blazor -t app-pro --preview |
|||
```` |
|||
|
|||
Please try it and provide feedback to us. Thanks in advance. |
|||
|
|||
> See the instructions in the *Get started with the Blazor UI* section above to properly create and run your application. |
|||
|
|||
### File Management Angular UI |
|||
|
|||
Angular UI for the [File Management](https://commercial.abp.io/modules/Volo.FileManagement) module is available with the version 3.2. You can add it to your solution using the ABP Suite. |
|||
|
|||
 |
|||
|
|||
### Profile Picture Management |
|||
|
|||
We've added profile picture management for the account module, so a user can select one of the options below for her profile picture; |
|||
|
|||
* Use the default placeholder as the avatar. |
|||
* Use [Gravatar](https://gravatar.com/) service to get the picture matching the email address of the user. |
|||
* Upload a file as the profile picture. |
|||
|
|||
 |
|||
|
|||
### Two Factor Authentication Features |
|||
|
|||
Created [features](https://docs.abp.io/en/abp/3.2/Features) and [settings](https://docs.abp.io/en/abp/3.2/Settings) to disable, enable or force to use 2FA on login for the tenants and users. |
|||
|
|||
### Upgrading the ABP Suite |
|||
|
|||
You can use the following command to upgrade the ABP Suite to the latest preview version: |
|||
|
|||
```` |
|||
abp suite update --preview |
|||
```` |
|||
|
|||
## Other News |
|||
|
|||
### The ABP Community |
|||
|
|||
**ABP Community** web site is constantly being improved and new articles are added. We will add "**commenting**" and "**rating**" features to the articles soon to increase the interactivity between the people. |
|||
|
|||
 |
|||
|
|||
If you have something to share with the ABP community or want to follow the project progress, please check the **[community.abp.io](https://community.abp.io/)**! |
|||
|
|||
### CMS Kit Project |
|||
|
|||
We are silently working on a project, named [CMS Kit](https://github.com/abpframework/abp/tree/dev/modules/cms-kit), for a few months. CMS Kit is a set of reusable CMS (Content Management System) components based on the ABP Framework. Some of the components currently being developed: |
|||
|
|||
* **Comments**; Allows users to comment under something (a blog post, a document, an image... etc). |
|||
* **Reactions**; Allows users to give reactions to something (a comment, a picture... etc.) using simple emoji icons. |
|||
* **Rating**; Allows users to rate some content from 1 to 5. |
|||
* **Newsletter**; Allows you to put a newsletter box to your web site to collect emails from users. |
|||
* **Contact**; Put a form to get message from the web site visitors. |
|||
|
|||
There are more planned components like articles, tags, votes, favorites, portfolio, image gallery, FAQ... etc. We will document and deploy these components when they get matured and ready to use. Some of them will be open source & free while some of them are paid (included in the [ABP Commercial](https://commercial.abp.io/) license). |
|||
|
|||
## Feedback |
|||
|
|||
Please try the ABP Framework 3.2.0 RC and [provide feedback](https://github.com/abpframework/abp/issues/new) to help us to release a more stable version. The planned release date for the [3.2.0 final](https://github.com/abpframework/abp/milestone/43) version is October 01. |
|||
|
After Width: | Height: | Size: 551 KiB |
|
After Width: | Height: | Size: 81 KiB |
|
After Width: | Height: | Size: 44 KiB |
|
After Width: | Height: | Size: 216 KiB |
|
After Width: | Height: | Size: 60 KiB |
|
After Width: | Height: | Size: 59 KiB |
|
After Width: | Height: | Size: 55 KiB |
@ -0,0 +1,47 @@ |
|||
# ABP Framework 3.2 Final Has Been Released |
|||
|
|||
ABP Framework & ABP Commercial 3.2 have been released today. |
|||
|
|||
Since all the new features are already explained in details with the [3.2 RC Announcement Post](https://blog.abp.io/abp/ABP-Framework-ABP-Commercial-3.2-RC-With-The-New-Blazor-UI), I will not repeat all the details again. Please read [the RC post](https://blog.abp.io/abp/ABP-Framework-ABP-Commercial-3.2-RC-With-The-New-Blazor-UI) for **new feature and changes** you may need to do for your solution while upgrading to the version 3.2. |
|||
|
|||
## Creating New Solutions |
|||
|
|||
You can create a new solution with the ABP Framework version 3.2 by either using the `abp new` command or using the **direct download** tab on the [get started page](https://abp.io/get-started). |
|||
|
|||
> See the [getting started document](https://docs.abp.io/en/abp/latest/Getting-Started) for details. |
|||
|
|||
## How to Upgrade an Existing Solution |
|||
|
|||
### Install/Update the ABP CLI |
|||
|
|||
First of all, install the ABP CLI or upgrade to the latest version. |
|||
|
|||
If you haven't installed yet: |
|||
|
|||
````bash |
|||
dotnet tool install -g Volo.Abp.Cli |
|||
```` |
|||
|
|||
To update an existing installation: |
|||
|
|||
```bash |
|||
dotnet tool update -g Volo.Abp.Cli |
|||
``` |
|||
|
|||
### ABP UPDATE Command |
|||
|
|||
[ABP CLI](https://docs.abp.io/en/abp/latest/CLI) provides a handy command to update all the ABP related NuGet and NPM packages in your solution with a single command: |
|||
|
|||
````bash |
|||
abp update |
|||
```` |
|||
|
|||
After the update command, check [the RC blog post](https://blog.abp.io/abp/ABP-Framework-ABP-Commercial-3.2-RC-With-The-New-Blazor-UI) to learn if you need to make any changes in your solution. |
|||
|
|||
> You may want to see the new [upgrading document](https://docs.abp.io/en/abp/latest/Upgrading). |
|||
|
|||
## About the Next Versions |
|||
|
|||
The next two versions (3.3 & 4.0) will be mostly related to completing the Blazor UI features and upgrading the ABP Framework & ecosystem to the .NET 5.0. |
|||
|
|||
The ultimate goal is to complete the version 4.0 with a stable Blazor UI with the fundamental features implemented and publish it just after the Microsoft lunches .NET 5 in this November. |
|||
@ -0,0 +1,67 @@ |
|||
# Build Command |
|||
|
|||
Building a .NET project is hard when the project references a project reference outside of the solution or even from a different GIT repository. This command builds a GIT repository and it's depending repositories or a single .NET solution File. In order ```build``` command to work, its **executing directory** or passed ```--working-directory``` parameter's directory must contain one of; |
|||
|
|||
* A .NET solution file (*.sln) |
|||
* abp-build-config.json |
|||
|
|||
When the executing directory (or ```--working-directory``` parameter's directory) contains a .NET solution file, ```build``` command builds all the projects in the related solution file and all project references on building project files recursively. |
|||
|
|||
When the executing directory (or ```--working-directory``` parameter's directory) contains a ```abp-build-config.json```, ```build``` command builds all changed projects form its last build and all project references on building project files recursively. |
|||
|
|||
# Build Command Config |
|||
|
|||
```abp-build-config.json``` contains properties below; |
|||
|
|||
* ```Name```: Name of the GIT repository. This can be friendly name of your GIT repository or any other unique string for the repository. |
|||
* ```RootPath```: Root path of the repository which contains ```.git``` folder. |
|||
* ```DependingRepositories```: Depending repository list of a repository. Each depending repository item contains same fields as a repository. |
|||
* ```IgnoredDirectories```: Relative directory paths to ignore while building a GIT repository. |
|||
|
|||
A sample ```abp-build-config.json``` looks like for a Windows OS; |
|||
|
|||
````json |
|||
{ |
|||
"Name": "main-repository", |
|||
"RootPath": "D:\\GitHub\\main-repository", |
|||
"DependingRepositories": [{ |
|||
"Name": "module-repository", |
|||
"RootPath": "D:\\GitHub\\module-repository" |
|||
}], |
|||
"IgnoredDirectories": [ |
|||
"utils" |
|||
] |
|||
} |
|||
```` |
|||
|
|||
# Build Status |
|||
|
|||
ABP CLI stores a build status file for builds using the repository friendly names and current branch names in the; |
|||
|
|||
* ```%USERPROFILE%\.abp\build\``` for Windows. |
|||
* ```$HOME/.abp/build/``` for Linux/macOS. |
|||
|
|||
and uses this file when building same repository next time and only builds affected projects and decreases the total build time. A sample build status file content looks like; |
|||
|
|||
````json |
|||
{ |
|||
"RepositoryName": "main-repository", |
|||
"BranchName": "dev", |
|||
"CommitId": "84ecde8ba275aeeb14d24a87ad46a1e941adf8ba", |
|||
"SucceedProjects": [{ |
|||
"CsProjPath": "D:\\GitHub\\main-repository\\BookStore\\BookStore.Web.csproj", |
|||
"CommitId": "84ecde8ba275aeeb14d24a87ad46a1e941adf8ba" |
|||
}], |
|||
"DependingRepositories": [{ |
|||
"RepositoryName": "module-repository", |
|||
"BranchName": "dev", |
|||
"CommitId": "0598b8e45af9507fc9ba8abf304e78fc7d434e04", |
|||
"SucceedProjects": [{ |
|||
"CsProjPath": "D:\\GitHub\\module-repository\\identity-module\Identity\\Identity.Web.csproj", |
|||
"CommitId": "0598b8e45af9507fc9ba8abf304e78fc7d434e04" |
|||
}], |
|||
"DependingRepositories": [] |
|||
}] |
|||
} |
|||
```` |
|||
|
|||
@ -0,0 +1,122 @@ |
|||
# How to Setup Azure Active Directory and Integrate Abp Angular Application |
|||
|
|||
This guide demonstrates how to register an application to Azure Active Directory and integrate AzureAD to an ABP angular application that enables users to sign in using OAuth 2.0 with credentials from **Azure Active Directory**. |
|||
|
|||
## Authentication Flow |
|||
|
|||
Abp angular applications use **Authentication Code with PKCE** (specs [here](https://tools.ietf.org/html/rfc7636)) which is the most suitable flow for spa applications by the time this article is written since implicit flow is deprecated. |
|||
|
|||
The most common question is; |
|||
|
|||
> Where to put OpenId connection code in angular project? |
|||
|
|||
The answer is, **you don't**. Abp angular application is integrated with backend code (HttpApi.Host project) where it loads the configurations, **permissions** etc. For none-tiered angular applications, **HttpApi.Host** project also has IdentityServer4 embedded; also serving as **Authorization Server**. Angular application authentication flow is shown below. |
|||
|
|||
<img src="auth-diagram.jpeg" alt="auth-diagram" style="zoom:50%;" /> |
|||
|
|||
> What if I want Azure AD as my authorization server and not IdentityServer? |
|||
|
|||
This means your application will be using AzureAD user store for authentication. By registering both angular app and HttpApi to AzureAD, authentication might work but **authorization won't**. Users need to be registered to Abp identity system for auditing, permissions etc. So the flow should be 3rd party registration. |
|||
|
|||
## Setting up OpenId Connection |
|||
|
|||
Lets start with adding OpenId connection. Open the **HttpApiHostModule.cs** and update the **ConfigureAuthentication** method as below: |
|||
|
|||
```csharp |
|||
JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear(); |
|||
JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Add("sub", ClaimTypes.NameIdentifier); |
|||
|
|||
context.Services.AddAuthentication() |
|||
.AddIdentityServerAuthentication(options => |
|||
{ |
|||
options.Authority = configuration["AuthServer:Authority"]; |
|||
options.RequireHttpsMetadata = false; |
|||
options.ApiName = "NonTieredAngular"; |
|||
options.JwtBackChannelHandler = new HttpClientHandler() |
|||
{ |
|||
ServerCertificateCustomValidationCallback = HttpClientHandler.DangerousAcceptAnyServerCertificateValidator |
|||
}; |
|||
}) |
|||
.AddOpenIdConnect("AzureOpenId", "Azure AD OpenId", options => |
|||
{ |
|||
options.Authority = "https://login.microsoftonline.com/" + configuration["AzureAd:TenantId"] + "/v2.0/"; |
|||
options.ClientId = configuration["AzureAd:ClientId"]; |
|||
options.ResponseType = OpenIdConnectResponseType.CodeIdToken; |
|||
options.CallbackPath = configuration["AzureAd:CallbackPath"]; |
|||
options.ClientSecret = configuration["AzureAd:ClientSecret"]; |
|||
options.RequireHttpsMetadata = false; |
|||
options.SaveTokens = true; |
|||
options.GetClaimsFromUserInfoEndpoint = true; |
|||
options.Scope.Add("email"); |
|||
}); |
|||
``` |
|||
|
|||
> If you are using tiered (separate identity server) application, open **IdentityServerModule.cs** and add the OpenIdConnection manually to **ConfigureServices** method as following: |
|||
|
|||
```csharp |
|||
public override void ConfigureServices(ServiceConfigurationContext context) |
|||
{ |
|||
var hostingEnvironment = context.Services.GetHostingEnvironment(); |
|||
var configuration = context.Services.GetConfiguration(); |
|||
|
|||
JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear(); |
|||
JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Add("sub", ClaimTypes.NameIdentifier); |
|||
|
|||
context.Services.AddAuthentication() |
|||
.AddOpenIdConnect("AzureOpenId", "Azure AD OpenId", options => |
|||
{ |
|||
... // Same configuration above |
|||
}); |
|||
``` |
|||
|
|||
Now we can add AzureAD settings. Open the **appsettings.json** located in **HttpApi.Host** project (or **IdentityServer** project if you are using tiered application). Add the following; |
|||
|
|||
```csharp |
|||
"AzureAd": { |
|||
"Instance": "https://login.microsoftonline.com/", |
|||
"TenantId": "<azureAd-tenant-id>", |
|||
"ClientId": "<azureAd-client-id>", |
|||
"Domain": "domain.onmicrosoft.com", |
|||
"CallbackPath": "/signin-azuread-oidc", |
|||
"ClientSecret": "<azureAd-client-secret>" |
|||
}, |
|||
``` |
|||
|
|||
Keep on mind that **App.SelfUrl** + **AzureAd.CallbackPath** will be used in AzureAD app registration. We'll update the AzureAd settings after registering the application in Azure Portal. |
|||
|
|||
## Setting up Azure Active Directory |
|||
|
|||
Navigate to Manage Azure Active Directory in [azure portal](https://portal.azure.com/). Go to **App registrations** on left side menu and hit New registration. |
|||
|
|||
 |
|||
|
|||
Enter a name for your application and **App.SelfUrl** + **AzureAd.CallbackPath** as redirect uri then register. |
|||
|
|||
<img src="azure-app-register.JPG" alt="azure-app-register" style="zoom:75%;" /> |
|||
|
|||
Now navigate to **Authentication** on the left menu and enable **ID tokens**. |
|||
|
|||
 |
|||
|
|||
We also need to set a client secret. Navigate to **Certificates & secrets** menu on the left and create a new client secret. |
|||
|
|||
 |
|||
|
|||
**Copy** the secret and update your appsettings.json **AzureAd.ClientSecret** field. |
|||
|
|||
 |
|||
|
|||
Also update your **AzureAd.TenantId** and **AzureAd.ClientId** fields with the information located under **Overview** menu. And that's all. |
|||
|
|||
Next time you hit login, you should be seeing login screen enabled Azure AD like below. |
|||
|
|||
 |
|||
|
|||
# FAQ |
|||
|
|||
* I am getting errors when trying to login to AzureAD. |
|||
* You can check [this article FAQ](https://community.abp.io/articles/how-to-use-the-azure-active-directory-authentication-for-mvc-razor-page-applications-4603b9cf) which covers many errors. |
|||
|
|||
|
|||
* But I don't want my users to see default login screen. I want my users to login **only** from AzureAD. |
|||
* You can **mimic** this behaviour by customizing the login page and instantly trigger Azure AD provider click. For more info, you can check [this article](https://community.abp.io/articles/how-to-customize-the-login-page-for-mvc-razor-page-applications-9a40f3cd). |
|||
|
After Width: | Height: | Size: 51 KiB |
|
After Width: | Height: | Size: 48 KiB |
|
After Width: | Height: | Size: 129 KiB |
|
After Width: | Height: | Size: 102 KiB |
|
After Width: | Height: | Size: 120 KiB |
|
After Width: | Height: | Size: 62 KiB |
|
After Width: | Height: | Size: 109 KiB |
@ -0,0 +1,317 @@ |
|||
# Using DevExtreme Angular Components With the ABP Framework |
|||
|
|||
In this article, I will show you how to integrate the [DevExpress Angular components](https://js.devexpress.com/Documentation/Guide/Angular_Components/DevExtreme_Angular_Components/) to a project created using the ABP Framework startup templates. Then I will use the [DataGrid](https://js.devexpress.com/Documentation/Guide/Widgets/DataGrid/Overview/) component to show a list of users on the UI. |
|||
|
|||
## Create the Project |
|||
|
|||
Let's create a new web application with the Angular UI using [ABP CLI](https://docs.abp.io/en/abp/latest/CLI#new): |
|||
|
|||
```shell |
|||
abp new DevExtremeAngular -u angular |
|||
``` |
|||
|
|||
> For detail information about how to generate and start up a project, please refer to the [official docs](https://docs.abp.io/en/abp/latest/Getting-Started?UI=NG&DB=EF&Tiered=No). For the scope of this post, we will not go into details of the backend applications. |
|||
|
|||
## Running the Solution |
|||
|
|||
### The Server Side |
|||
|
|||
Server side contains multiple projects in the solution: |
|||
|
|||
 |
|||
|
|||
Run following projects in order; |
|||
|
|||
* Run `DevExtremeAngular.DbMigrator` to create the database and seed the initial data. |
|||
* Run `DevExtremeAngular.HttpApi.Host` project to make the backend API up & running. |
|||
|
|||
### The Angular Application |
|||
|
|||
Open a command line terminal and navigate to `angular` folder then run `yarn` or `npm install` based on which package you are using. |
|||
|
|||
After installation process is done, you can start your angular project by running `yarn start` or `npm start`. This command should serve the application and open the application in your default browser. If it doesn't open, you can navigate to http://localhost:4200 in your browser: |
|||
|
|||
 |
|||
|
|||
You can login to the application by using following credentials: |
|||
|
|||
> _Default admin username is **admin** and password is **1q2w3E\***_ |
|||
|
|||
 |
|||
|
|||
After successful login, you should be redirected to home page. |
|||
|
|||
## Install DevExtreme |
|||
|
|||
You can follow [the guide](https://js.devexpress.com/Documentation/Guide/Angular_Components/Getting_Started/Add_DevExtreme_to_an_Angular_CLI_Application/) provided by **DevExtreme** team or apply the following steps. |
|||
|
|||
* `npm install devextreme devextreme-angular` or `yarn add devextreme devextreme-angular` |
|||
* Import given two following styles in `angular.json` file: |
|||
|
|||
```javascript |
|||
// ... |
|||
"styles": [ |
|||
// ... |
|||
"src/styles.scss", |
|||
|
|||
"node_modules/devextreme/dist/css/dx.common.css", |
|||
"node_modules/devextreme/dist/css/dx.light.css" |
|||
] |
|||
``` |
|||
|
|||
* Add `dx-viewport` to classes of `body` in `index.html` |
|||
|
|||
```html |
|||
<body class="bg-light dx-viewport"> |
|||
<app-root> |
|||
<div class="donut centered"></div> |
|||
</app-root> |
|||
</body> |
|||
``` |
|||
|
|||
After completing these steps, you need to restart the angular application. |
|||
|
|||
## Create a lazy Angular Module for DevExtreme Demo |
|||
|
|||
Let's create a module which will be loaded lazily. |
|||
|
|||
Open up a terminal and navigate to `angular` to run following command. |
|||
|
|||
```shell |
|||
ng g m dev-extreme --route dev-extreme --module app |
|||
``` |
|||
|
|||
...or with `npx`, if you do not have `angular-cli` installed... |
|||
|
|||
```shell |
|||
npx ng g m dev-extreme --route dev-extreme --module app |
|||
``` |
|||
|
|||
Your terminal should log the following output: |
|||
|
|||
```shell |
|||
CREATE src/app/dev-extreme/dev-extreme-routing.module.ts (361 bytes) |
|||
CREATE src/app/dev-extreme/dev-extreme.module.ts (379 bytes) |
|||
CREATE src/app/dev-extreme/dev-extreme.component.scss (0 bytes) |
|||
CREATE src/app/dev-extreme/dev-extreme.component.html (26 bytes) |
|||
CREATE src/app/dev-extreme/dev-extreme.component.spec.ts (655 bytes) |
|||
CREATE src/app/dev-extreme/dev-extreme.component.ts (295 bytes) |
|||
UPDATE src/app/app-routing.module.ts (362 bytes) |
|||
``` |
|||
|
|||
The Angular CLI has created a module and configured it to lazy-load at `/dev-extreme` path. |
|||
|
|||
The last step to be able to see our newly created module in the browser, open `route.provider.ts` and edit the array being added into the routes. |
|||
|
|||
```typescript |
|||
// ... |
|||
routes.add([ |
|||
{ |
|||
path: '/', |
|||
name: '::Menu:Home', |
|||
iconClass: 'fas fa-home', |
|||
order: 1, |
|||
layout: eLayoutType.application, |
|||
}, |
|||
{ |
|||
path: '/dev-extreme', |
|||
name: 'Dev Extreme', |
|||
order: 2, |
|||
layout: eLayoutType.application, |
|||
}, |
|||
]); |
|||
// ... |
|||
``` |
|||
|
|||
After completing the steps above, you should be able to see `Dev Extreme` on the header and when you click on it, you should be redirected to `/dev-extreme` page and see the following message on the screen. |
|||
|
|||
 |
|||
|
|||
## Display users on the dev-extreme page |
|||
|
|||
For this demo, we will list users on the screen. We already have `admin` as our first user. |
|||
|
|||
Let's add couple of more to the list in `Administration -> Identity Management -> Users` page. |
|||
|
|||
 |
|||
|
|||
Now we are ready to fetch our users and display them on `/dev-extreme` page. |
|||
|
|||
Firstly, let's create a service for our component. |
|||
|
|||
Navigate to the `dev-extreme` folder and run following command. If you run this command at the root, the service will be generated next to `app.module.ts` |
|||
|
|||
```shell |
|||
ng g s dev-extreme |
|||
``` |
|||
|
|||
Following files should be created |
|||
|
|||
```shell |
|||
CREATE src/app/dev-extreme/dev-extreme.service.spec.ts (378 bytes) |
|||
CREATE src/app/dev-extreme/dev-extreme.service.ts (139 bytes) |
|||
``` |
|||
|
|||
Let's import and inject `IdentityService` as dependency in `dev-extreme.service.ts`. After then, let's create a stream called `users$` to retrieve the users. |
|||
|
|||
`identityService.getUsers` returns `ABP.PagedResponse` which contains two fields, `items` and `totalCount`. We are only interested in `items` for now. |
|||
|
|||
When we apply the steps described above, the final version of `dev-extreme.service` should be as follows |
|||
|
|||
```typescript |
|||
import { Injectable } from '@angular/core'; |
|||
import { map } from 'rxjs/operators'; |
|||
import { IdentityService } from '@abp/ng.identity'; |
|||
|
|||
@Injectable({ |
|||
providedIn: 'root', |
|||
}) |
|||
export class DevExtremeService { |
|||
users$ = this.service.getUsers().pipe(map((result) => result.items)); |
|||
|
|||
constructor(private service: IdentityService) {} |
|||
} |
|||
``` |
|||
|
|||
Now we can simply inject `DevExtremeService` as public and utilize `users$` stream in `dev-extreme.component.ts` as follows: |
|||
|
|||
```typescript |
|||
import { Component } from '@angular/core'; |
|||
import { DevExtremeService } from './dev-extreme.service'; |
|||
|
|||
@Component({ |
|||
selector: 'app-dev-extreme', |
|||
templateUrl: './dev-extreme.component.html', |
|||
styleUrls: ['./dev-extreme.component.scss'], |
|||
}) |
|||
export class DevExtremeComponent { |
|||
constructor(public service: DevExtremeService) {} |
|||
} |
|||
``` |
|||
|
|||
And use it within `dev-extreme.component.html` |
|||
|
|||
```html |
|||
<ng-container *ngIf="service.users$ | async as users"> |
|||
<ul> |
|||
<li *ngFor="let user of users"> |
|||
{{ user.name }} |
|||
</li> |
|||
</ul> |
|||
</ng-container> |
|||
``` |
|||
|
|||
This should list names of the users on the screen |
|||
|
|||
 |
|||
|
|||
## Use DxDataGrid to list the users |
|||
|
|||
You can take a look at [demo](https://js.devexpress.com/Demos/WidgetsGallery/Demo/DataGrid/ColumnCustomization/Angular/Light/) provided by **DevExtreme** team or apply the following steps. |
|||
|
|||
Now, our application is ready to use `dx-data-grid` in `dev-extreme.component.ts` |
|||
|
|||
Firstly, we need to import `DxDataGridModule` in our module as follows. |
|||
|
|||
```typescript |
|||
// ... |
|||
|
|||
import { DxDataGridModule } from 'devextreme-angular'; |
|||
|
|||
@NgModule({ |
|||
// ... |
|||
imports: [ |
|||
// ... |
|||
DxDataGridModule |
|||
], |
|||
}) |
|||
export class DevExtremeModule {} |
|||
``` |
|||
|
|||
At this point `dx-data-grid` is avaliable within our module and we can use it in our template. |
|||
|
|||
Change `dev-extreme.component.html` to the following |
|||
|
|||
```html |
|||
<ng-container *ngIf="service.users$ | async as users"> |
|||
<dx-data-grid [dataSource]="users"></dx-data-grid> |
|||
</ng-container> |
|||
``` |
|||
|
|||
It should display a table on the screen |
|||
|
|||
 |
|||
|
|||
Since, we did not specify any columns, `dx-data-grid` displayed every column avaliable. Let's pick some columns to make it more readable. |
|||
|
|||
Change `dev-extreme.component.html` to the following: |
|||
|
|||
```html |
|||
<ng-container *ngIf="service.users$ | async as users"> |
|||
<dx-data-grid [dataSource]="users"> |
|||
<dxi-column dataField="userName"></dxi-column> |
|||
<dxi-column dataField="name"></dxi-column> |
|||
<dxi-column dataField="surname"></dxi-column> |
|||
<dxi-column dataField="email"></dxi-column> |
|||
<dxi-column dataField="phoneNumber"></dxi-column> |
|||
</dx-data-grid> |
|||
</ng-container> |
|||
``` |
|||
|
|||
which will display following table on the screen |
|||
|
|||
 |
|||
|
|||
We can also utilize `abpLocalization` pipe to translate the headers of the table. To use `abpLocalization` pipe in our templates, we need to import `CoreModule` from `@abp/ng.core` into our module. |
|||
|
|||
```typescript |
|||
import { CoreModule } from '@abp/ng.core'; |
|||
|
|||
@NgModule({ |
|||
// ... |
|||
imports: [ |
|||
// ... |
|||
CoreModule |
|||
], |
|||
}) |
|||
export class DevExtremeModule {} |
|||
``` |
|||
|
|||
And change the template to the following: |
|||
|
|||
```html |
|||
<ng-container *ngIf="service.users$ | async as users"> |
|||
<dx-data-grid [dataSource]="users"> |
|||
<dxi-column |
|||
dataField="userName" |
|||
[caption]="'AbpIdentity::DisplayName:UserName' | abpLocalization" |
|||
></dxi-column> |
|||
<dxi-column |
|||
dataField="name" |
|||
[caption]="'AbpIdentity::DisplayName:Name' | abpLocalization" |
|||
></dxi-column> |
|||
<dxi-column |
|||
dataField="surname" |
|||
[caption]="'AbpIdentity::DisplayName:Surname' | abpLocalization" |
|||
></dxi-column> |
|||
<dxi-column |
|||
dataField="email" |
|||
[caption]="'AbpIdentity::DisplayName:Email' | abpLocalization" |
|||
></dxi-column> |
|||
<dxi-column |
|||
dataField="phoneNumber" |
|||
[caption]="'AbpIdentity::DisplayName:PhoneNumber' | abpLocalization" |
|||
></dxi-column> |
|||
</dx-data-grid> |
|||
</ng-container> |
|||
``` |
|||
|
|||
The headers should change when a new language is selected; |
|||
|
|||
 |
|||
|
|||
## Conclusion |
|||
|
|||
In this article, we have seen how to integrate `DevExtreme` angular components into a project generated by `ABP CLI`. |
|||
|
|||
You can download source code of [the demo here](https://github.com/abpframework/abp-samples/tree/master/DevExtreme-Angular). |
|||
|
After Width: | Height: | Size: 17 KiB |
|
After Width: | Height: | Size: 828 KiB |
|
After Width: | Height: | Size: 27 KiB |
|
After Width: | Height: | Size: 22 KiB |
|
After Width: | Height: | Size: 50 KiB |
|
After Width: | Height: | Size: 34 KiB |
|
After Width: | Height: | Size: 38 KiB |
|
After Width: | Height: | Size: 4.3 KiB |
|
After Width: | Height: | Size: 42 KiB |
@ -0,0 +1,43 @@ |
|||
# Redis Cache |
|||
|
|||
ABP Framework [Caching System](Caching.md) extends the [ASP.NET Core distributed cache](https://docs.microsoft.com/en-us/aspnet/core/performance/caching/distributed). So, **any provider** supported by the standard ASP.NET Core distributed cache can be usable in your application and can be configured just like **documented by Microsoft**. |
|||
|
|||
However, ABP provides an **integration package** for Redis Cache: [Volo.Abp.Caching.StackExchangeRedis](https://www.nuget.org/packages/Volo.Abp.Caching.StackExchangeRedis). There are two reasons for using this package, instead of the standard [Microsoft.Extensions.Caching.StackExchangeRedis](https://www.nuget.org/packages/Microsoft.Extensions.Caching.StackExchangeRedis/) package. |
|||
|
|||
1. It implements `SetManyAsync` and `GetManyAsync` methods. These are not standard methods of the Microsoft Caching library, but added by the ABP Framework [Caching](Caching.md) system. They **significiantly increases the performance** when you need to set/get multiple cache items with a single method call. |
|||
2. It **simplifies** the Redis cache **configuration** (will be explained below). |
|||
|
|||
> Volo.Abp.Caching.StackExchangeRedis is already uses the Microsoft.Extensions.Caching.StackExchangeRedis package, but extends and improves it. |
|||
|
|||
## Installation |
|||
|
|||
> This package is already installed in the application startup template if it is using Redis. |
|||
|
|||
Open a command line in the folder of your `.csproj` file and type the following ABP CLI command: |
|||
|
|||
````bash |
|||
abp add-package Volo.Abp.Caching.StackExchangeRedis |
|||
```` |
|||
|
|||
## Configuration |
|||
|
|||
Volo.Abp.Caching.StackExchangeRedis package automatically gets the redis [configuration](Configuration.md) from the `IConfiguration`. So, for example, you can set your configuration inside the `appsettings.json`: |
|||
|
|||
````js |
|||
"Redis": { |
|||
"Configuration": "127.0.0.1" |
|||
} |
|||
```` |
|||
|
|||
Alternatively you can configure the standard [RedisCacheOptions](https://docs.microsoft.com/en-us/dotnet/api/microsoft.extensions.caching.stackexchangeredis.rediscacheoptions) [options](Options.md) class in the `ConfigureServices` method of your [module](Module-Development-Basics.md): |
|||
|
|||
````csharp |
|||
Configure<RedisCacheOptions>(options => |
|||
{ |
|||
//... |
|||
}); |
|||
```` |
|||
|
|||
## See Also |
|||
|
|||
* [Caching](Caching.md) |
|||
|
After Width: | Height: | Size: 8.6 KiB |
|
After Width: | Height: | Size: 19 KiB |
|
After Width: | Height: | Size: 82 KiB |
|
After Width: | Height: | Size: 61 KiB |
|
After Width: | Height: | Size: 63 KiB |
|
After Width: | Height: | Size: 27 KiB |
|
After Width: | Height: | Size: 7.6 KiB |
|
After Width: | Height: | Size: 40 KiB |
|
After Width: | Height: | Size: 32 KiB |
@ -0,0 +1,98 @@ |
|||
# About Feature Libraries |
|||
|
|||
ABP has an ever-growing number of feature modules and [introducing a new one](../../Module-Development-Basics.md) is always possible. When the UI is Angular, these features have modular Angular libraries accompanying them. |
|||
|
|||
## Feature Library Content |
|||
|
|||
Each library has at least two modules: |
|||
|
|||
1. The main module contains all components, services, types, enums, etc. to deliver the required UI when the feature is loaded. From here on, we will refer to these modules as **"feature module"**. |
|||
2. There is also a **"config module"** per library which helps us configure applications to run these modules or make them accessible. |
|||
|
|||
## How to Add a Feature Library to Your Project |
|||
|
|||
<!-- TODO: Insert info on CLI `add-module` command here when the schematic is ready. --> |
|||
|
|||
The manual setup of a feature library has three steps: |
|||
|
|||
### 1. Install the Library |
|||
|
|||
Feature libraries are usually published as an npm package. If a library you want to use does not exist in your project, you may install it via the following command: |
|||
|
|||
```shell |
|||
yarn add @my-company-name/my-project-name |
|||
``` |
|||
|
|||
...or... |
|||
|
|||
```shell |
|||
npm install @my-company-name/my-project-name |
|||
``` |
|||
|
|||
The `my-company-name` and `my-project-name` parts are going to change according to the package you want to use. For example, if we want to install the ABP Identity module, the package installation will be as seen below: |
|||
|
|||
```shell |
|||
yarn add @abp/ng.identity |
|||
``` |
|||
|
|||
> Identity is used just as an example. If you have initiated your project with ABP CLI or ABP Suite, the identity library will already be installed and configured in your project. |
|||
|
|||
### 2. Import the Config Module |
|||
|
|||
As of ABP v3.0, every lazy-loaded module has a config module available via a secondary entry point on the same package. Importing them in your root module looks like this: |
|||
|
|||
```js |
|||
import { IdentityConfigModule } from "@abp/ng.identity/config"; |
|||
|
|||
@NgModule({ |
|||
imports: [ |
|||
// other imports |
|||
IdentityConfigModule.forRoot(), |
|||
], |
|||
// providers, declarations, and bootstrap |
|||
}) |
|||
export class AppModule {} |
|||
``` |
|||
|
|||
We need the config modules for actions required before feature modules are loaded (lazily). For example, the above import configures the menu to display links to identity pages. |
|||
|
|||
Furthermore, depending on the library, the `.forRoot` static method may receive some options that configure how the feature works. |
|||
|
|||
### 3. Import the Feature Module |
|||
|
|||
Finally, the feature module should be [loaded lazily via Angular router](https://angular.io/guide/lazy-loading-ngmodules). If you open the `/src/app/app-routing.module.ts` file, you should see `IdentityModule` is loaded exactly as follows: |
|||
|
|||
```js |
|||
import { NgModule } from "@angular/core"; |
|||
import { RouterModule, Routes } from "@angular/router"; |
|||
|
|||
const routes: Routes = [ |
|||
// other routes |
|||
{ |
|||
path: "identity", |
|||
loadChildren: () => |
|||
import("@abp/ng.identity").then((m) => m.IdentityModule.forLazy()), |
|||
}, |
|||
// other routes |
|||
]; |
|||
|
|||
@NgModule({ |
|||
imports: [RouterModule.forRoot(routes)], |
|||
exports: [RouterModule], |
|||
}) |
|||
export class AppRoutingModule {} |
|||
``` |
|||
|
|||
When you load the identity feature like this, the "Users" page, for example, will have a route path of `/identity/users`. <sup id="a-modify-route">[1](#f-modify-route)</sup> |
|||
|
|||
Depending on the library, the `.forLazy` static method may also receive some options that configure how the feature works. |
|||
|
|||
--- |
|||
|
|||
<sup id="f-modify-route"><b>1</b></sup> _Libraries expect to work at a predefined path. Please check [how to patch a navigation element](./Modifying-the-Menu.md#how-to-patch-or-remove-a-navigation-element), if you want to use a different path from the default one (e.g. '/identity')._ <sup>[↩](#a-modify-route)</sup> |
|||
|
|||
--- |
|||
|
|||
## What's Next? |
|||
|
|||
- [Service Proxies](./Service-Proxies.md) |
|||
@ -0,0 +1,346 @@ |
|||
# PWA Configuration |
|||
|
|||
[Progressive Web Apps](https://web.dev/progressive-web-apps/) are web applications which, although not as integrated to the OS as a native app, can take advantage of native features. They can be discovered via search engines, installed on devices with a single tap or click, and shared via a regular link. They also can work offline and get updates when new content is available. |
|||
|
|||
Converting your Angular application to a PWA is easy. |
|||
|
|||
## 1. Install Angular PWA |
|||
|
|||
Run the following command in the root folder of your Angular application: |
|||
|
|||
```shell |
|||
yarn ng add @angular/pwa |
|||
``` |
|||
|
|||
...or... |
|||
|
|||
```shell |
|||
npm run ng add @angular/pwa |
|||
``` |
|||
|
|||
This will install the `@angular/service-worker` package and make your default app a PWA. Alternatively, you may add `project` parameter to target a specific app in your workspace: |
|||
|
|||
```shell |
|||
yarn ng add @angular/pwa --project MyProjectName |
|||
``` |
|||
|
|||
Here is the output of the command: |
|||
|
|||
<img alt="Angular PWA updates and creates files" src="./images/pwa-configuration-ng-add.png" width="400px" style="max-width:100%"> |
|||
|
|||
So, Angular CLI updates some files and add a few others: |
|||
|
|||
- **ngsw-config.json** is where the [service worker configuration](https://angular.io/guide/service-worker-config) is placed. Not all PWAs have this file. It is specific to Angular. |
|||
- **manifest.webmanifest** is a [web app manifest](https://developer.mozilla.org/en-US/docs/Web/Manifest) and provides information about your app in JSON format. |
|||
- **icons** are placeholder icons that are referred to in your web app manifest. We will replace these in a minute. |
|||
- **angular.json** has following modifications: |
|||
- `assets` include _manifest.webmanifest_. |
|||
- `serviceWorker` is `true` in production build. |
|||
- `ngswConfigPath` refers to _ngsw-config.json_. |
|||
- **package.json** has _@angular/service-worker_ as a new dependency. |
|||
- **app.module.ts** imports `ServiceWorkerModule` and registers a service worker filename. |
|||
- **index.html** has following modifications: |
|||
- A `<link>` element that refers to _manifest.webmanifest_. |
|||
- A `<meta>` tag that sets a theme color. |
|||
|
|||
## 2. Update the Web App Manifest |
|||
|
|||
### 2.1. Set the Name of Your App |
|||
|
|||
The `name` and the `short_name` properties in the generated manifest are derived from your project name. Let's change them. |
|||
|
|||
Open the _manifest.webmanifest_ file and update `name` and `short_name` props: |
|||
|
|||
```json |
|||
{ |
|||
/* rest of the manifest meta data */ |
|||
"short_name": "My Project", |
|||
"name": "My Project: My Catch-Phrase" |
|||
} |
|||
``` |
|||
|
|||
The short name must be really short because it will be displayed on anywhere with limited space, like the launcher and the home screen. |
|||
|
|||
### 2.2. Add a Description |
|||
|
|||
The `@angular/pwa` schematic we just added does not insert a description to your manifest file, but, according to [web app manifest standards](https://www.w3.org/TR/appmanifest/#description-member), you should. |
|||
|
|||
So, open the _manifest.webmanifest_ file and place the description as seen below: |
|||
|
|||
```json |
|||
{ |
|||
/* rest of the manifest meta data */ |
|||
"description": "My short project description giving a slightly better idea about my app" |
|||
} |
|||
``` |
|||
|
|||
As a bonus, providing a description [along with other criteria](https://docs.microsoft.com/en-us/microsoft-edge/progressive-web-apps-edgehtml/microsoft-store#criteria-for-automatic-submission) helps Bing web crawler to index your app and automatically submit your app to Microsoft Store in `.appx` format. |
|||
|
|||
### 2.3. Set App Colors |
|||
|
|||
Angular generates the manifest file with a default `theme_color` and `background_color`. Change these according to your brand identity: |
|||
|
|||
Open the _manifest.webmanifest_ file and update `theme_color` and `background_color` properties: |
|||
|
|||
```json |
|||
{ |
|||
/* rest of the manifest meta data */ |
|||
"theme_color": "#000000", |
|||
"background_color": "#ffffff" |
|||
} |
|||
``` |
|||
|
|||
Then open _index.html_ and change the theme color meta tag as below: |
|||
|
|||
```html |
|||
<meta name="theme-color" content="#000000" /> |
|||
``` |
|||
|
|||
### 2.4. Replace App Icons & Add Splash Screens |
|||
|
|||
We need to update the icons and add some splash screens. This normally is time-consuming, but we will use the marvelous [pwa-asset-generator](https://github.com/onderceylan/pwa-asset-generator#readme) library. |
|||
|
|||
First, open the _manifest.webmanifest_ file and remove all elements in the `icons` property: |
|||
|
|||
```json |
|||
{ |
|||
/* rest of the manifest meta data */ |
|||
"icons": [] |
|||
} |
|||
``` |
|||
|
|||
Then, run the following command in your terminal (changing the path of course): |
|||
|
|||
```shell |
|||
npx pwa-asset-generator /path/to/your/logo.png ./src/assets/pwa -i ./src/index.html -m ./src/manifest.webmanifest |
|||
``` |
|||
|
|||
Open the _manifest.webmanifest_ file again. You will see this: |
|||
|
|||
```json |
|||
{ |
|||
/* rest of the manifest meta data */ |
|||
"icons": [ |
|||
{ |
|||
"src": "../manifest-icon-192.png", |
|||
"sizes": "192x192", |
|||
"type": "image/png", |
|||
"purpose": "maskable any" |
|||
}, |
|||
{ |
|||
"src": "../manifest-icon-512.png", |
|||
"sizes": "512x512", |
|||
"type": "image/png", |
|||
"purpose": "maskable any" |
|||
} |
|||
] |
|||
} |
|||
``` |
|||
|
|||
In addition to updated icons, the library will generate splash screens. However, Apple requires all splash screens to be added in your _index.html_ and displays a blank screen at startup otherwise. So, the following tags will be inserted into the _index.html_ file: |
|||
|
|||
```html |
|||
<link |
|||
rel="apple-touch-icon" |
|||
sizes="180x180" |
|||
href="assets/pwa/apple-icon-180.jpg" |
|||
/> |
|||
<link |
|||
rel="apple-touch-icon" |
|||
sizes="167x167" |
|||
href="assets/pwa/apple-icon-167.jpg" |
|||
/> |
|||
<link |
|||
rel="apple-touch-icon" |
|||
sizes="152x152" |
|||
href="assets/pwa/apple-icon-152.jpg" |
|||
/> |
|||
<link |
|||
rel="apple-touch-icon" |
|||
sizes="120x120" |
|||
href="assets/pwa/apple-icon-120.jpg" |
|||
/> |
|||
|
|||
<meta name="apple-mobile-web-app-capable" content="yes" /> |
|||
|
|||
<link |
|||
rel="apple-touch-startup-image" |
|||
href="assets/pwa/apple-splash-2048-2732.jpg" |
|||
media="(device-width: 1024px) and (device-height: 1366px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)" |
|||
/> |
|||
<link |
|||
rel="apple-touch-startup-image" |
|||
href="assets/pwa/apple-splash-2732-2048.jpg" |
|||
media="(device-width: 1024px) and (device-height: 1366px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)" |
|||
/> |
|||
<link |
|||
rel="apple-touch-startup-image" |
|||
href="assets/pwa/apple-splash-1668-2388.jpg" |
|||
media="(device-width: 834px) and (device-height: 1194px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)" |
|||
/> |
|||
<link |
|||
rel="apple-touch-startup-image" |
|||
href="assets/pwa/apple-splash-2388-1668.jpg" |
|||
media="(device-width: 834px) and (device-height: 1194px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)" |
|||
/> |
|||
<link |
|||
rel="apple-touch-startup-image" |
|||
href="assets/pwa/apple-splash-1536-2048.jpg" |
|||
media="(device-width: 768px) and (device-height: 1024px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)" |
|||
/> |
|||
<link |
|||
rel="apple-touch-startup-image" |
|||
href="assets/pwa/apple-splash-2048-1536.jpg" |
|||
media="(device-width: 768px) and (device-height: 1024px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)" |
|||
/> |
|||
<link |
|||
rel="apple-touch-startup-image" |
|||
href="assets/pwa/apple-splash-1668-2224.jpg" |
|||
media="(device-width: 834px) and (device-height: 1112px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)" |
|||
/> |
|||
<link |
|||
rel="apple-touch-startup-image" |
|||
href="assets/pwa/apple-splash-2224-1668.jpg" |
|||
media="(device-width: 834px) and (device-height: 1112px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)" |
|||
/> |
|||
<link |
|||
rel="apple-touch-startup-image" |
|||
href="assets/pwa/apple-splash-1620-2160.jpg" |
|||
media="(device-width: 810px) and (device-height: 1080px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)" |
|||
/> |
|||
<link |
|||
rel="apple-touch-startup-image" |
|||
href="assets/pwa/apple-splash-2160-1620.jpg" |
|||
media="(device-width: 810px) and (device-height: 1080px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)" |
|||
/> |
|||
<link |
|||
rel="apple-touch-startup-image" |
|||
href="assets/pwa/apple-splash-1242-2688.jpg" |
|||
media="(device-width: 414px) and (device-height: 896px) and (-webkit-device-pixel-ratio: 3) and (orientation: portrait)" |
|||
/> |
|||
<link |
|||
rel="apple-touch-startup-image" |
|||
href="assets/pwa/apple-splash-2688-1242.jpg" |
|||
media="(device-width: 414px) and (device-height: 896px) and (-webkit-device-pixel-ratio: 3) and (orientation: landscape)" |
|||
/> |
|||
<link |
|||
rel="apple-touch-startup-image" |
|||
href="assets/pwa/apple-splash-1125-2436.jpg" |
|||
media="(device-width: 375px) and (device-height: 812px) and (-webkit-device-pixel-ratio: 3) and (orientation: portrait)" |
|||
/> |
|||
<link |
|||
rel="apple-touch-startup-image" |
|||
href="assets/pwa/apple-splash-2436-1125.jpg" |
|||
media="(device-width: 375px) and (device-height: 812px) and (-webkit-device-pixel-ratio: 3) and (orientation: landscape)" |
|||
/> |
|||
<link |
|||
rel="apple-touch-startup-image" |
|||
href="assets/pwa/apple-splash-828-1792.jpg" |
|||
media="(device-width: 414px) and (device-height: 896px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)" |
|||
/> |
|||
<link |
|||
rel="apple-touch-startup-image" |
|||
href="assets/pwa/apple-splash-1792-828.jpg" |
|||
media="(device-width: 414px) and (device-height: 896px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)" |
|||
/> |
|||
<link |
|||
rel="apple-touch-startup-image" |
|||
href="assets/pwa/apple-splash-1080-1920.jpg" |
|||
media="(device-width: 360px) and (device-height: 640px) and (-webkit-device-pixel-ratio: 3) and (orientation: portrait)" |
|||
/> |
|||
<link |
|||
rel="apple-touch-startup-image" |
|||
href="assets/pwa/apple-splash-1920-1080.jpg" |
|||
media="(device-width: 360px) and (device-height: 640px) and (-webkit-device-pixel-ratio: 3) and (orientation: landscape)" |
|||
/> |
|||
<link |
|||
rel="apple-touch-startup-image" |
|||
href="assets/pwa/apple-splash-750-1334.jpg" |
|||
media="(device-width: 375px) and (device-height: 667px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)" |
|||
/> |
|||
<link |
|||
rel="apple-touch-startup-image" |
|||
href="assets/pwa/apple-splash-1334-750.jpg" |
|||
media="(device-width: 375px) and (device-height: 667px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)" |
|||
/> |
|||
<link |
|||
rel="apple-touch-startup-image" |
|||
href="assets/pwa/apple-splash-640-1136.jpg" |
|||
media="(device-width: 320px) and (device-height: 568px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)" |
|||
/> |
|||
<link |
|||
rel="apple-touch-startup-image" |
|||
href="assets/pwa/apple-splash-1136-640.jpg" |
|||
media="(device-width: 320px) and (device-height: 568px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)" |
|||
/> |
|||
``` |
|||
|
|||
## 3. Configure Service Worker |
|||
|
|||
### 3.1 Modify Asset Groups |
|||
|
|||
Angular has defined some static files to be cached by the service worker, but they are not 100% accurate. Let's change it. |
|||
|
|||
Open _ngsw-config.json_ file and replace its content with this: |
|||
|
|||
```json |
|||
{ |
|||
"$schema": "./node_modules/@angular/service-worker/config/schema.json", |
|||
"index": "/index.html", |
|||
"assetGroups": [ |
|||
{ |
|||
"name": "app", |
|||
"installMode": "prefetch", |
|||
"resources": { |
|||
"files": [ |
|||
"/favicon.ico", |
|||
"/index.html", |
|||
"/manifest.webmanifest", |
|||
"/*.css", |
|||
"/common-es2015.*.js", |
|||
"/main-es2015.*.js", |
|||
"/polyfills-es2015.*.js", |
|||
"/runtime-es2015.*.js", |
|||
"/vendor-es2015.*.js" |
|||
] |
|||
} |
|||
}, |
|||
{ |
|||
"name": "modules", |
|||
"installMode": "lazy", |
|||
"updateMode": "prefetch", |
|||
"resources": { |
|||
"files": [ |
|||
"/*-es2015.*.js", |
|||
"!/common-es2015.*.js", |
|||
"!/main-es2015.*.js", |
|||
"!/polyfills-es2015.*.js", |
|||
"!/runtime-es2015.*.js", |
|||
"!/vendor-es2015.*.js" |
|||
] |
|||
} |
|||
}, |
|||
{ |
|||
"name": "assets", |
|||
"installMode": "lazy", |
|||
"updateMode": "prefetch", |
|||
"resources": { |
|||
"files": [ |
|||
"/assets/**", |
|||
"/*.(eot|svg|cur|jpg|png|webp|gif|otf|ttf|woff|woff2|ani)" |
|||
] |
|||
} |
|||
} |
|||
] |
|||
} |
|||
``` |
|||
|
|||
In case you want to cache other static files, please refer to the [service worker configuration document](https://angular.io/guide/service-worker-config#assetgroups) on Angular.io. |
|||
|
|||
### 3.2 Set Data Groups |
|||
|
|||
This part is unique to your project. We recommend being very careful about which endpoints to cache. Please refer to [service worker configuration document](https://angular.io/guide/service-worker-config#datagroups) on Angular.io for details. |
|||
|
|||
## What's Next? |
|||
|
|||
- [Config State](./Config-State.md) |
|||
@ -0,0 +1,212 @@ |
|||
# ABP Angular Quick Start |
|||
|
|||
## How to Prepare Development Environment |
|||
|
|||
Please follow the steps below to prepare your development environment for Angular. |
|||
|
|||
1. **Install Node.js:** Please visit [Node.js downloads page](https://nodejs.org/en/download/) and download proper Node.js v12 or v14 installer for your OS. An alternative is to install [NVM](https://github.com/nvm-sh/nvm) and use it to have multiple versions of Node.js in your operating system. |
|||
2. **[Optional] Install Yarn:** You may install Yarn v1 (not v2) following the instructions on [the installation page](https://classic.yarnpkg.com/en/docs/install). Yarn v1 delivers an arguably better developer experience compared to npm v6 and below. You may skip this step and work with npm, which is built-in in Node.js, instead. |
|||
3. **[Optional] Install VS Code:** [VS Code](https://code.visualstudio.com/) is a free, open-source IDE which works seamlessly with TypeScript. Although you can use any IDE including Visual Studio or Rider, VS Code will most likely deliver the best developer experience when it comes to Angular projects. ABP project templates even contain plugin recommendations for VS Code users, which VS Code will ask you to install when you open the Angular project folder. Here is a list of recommended extensions: |
|||
- [Angular Language Service](https://marketplace.visualstudio.com/items?itemName=angular.ng-template) |
|||
- [Prettier - Code formatter](https://marketplace.visualstudio.com/items?itemName=esbenp.prettier-vscode) |
|||
- [TSLint](https://marketplace.visualstudio.com/items?itemName=ms-vscode.vscode-typescript-tslint-plugin) |
|||
- [Visual Studio IntelliCode](https://marketplace.visualstudio.com/items?itemName=visualstudioexptteam.vscodeintellicode) |
|||
- [Path Intellisense](https://marketplace.visualstudio.com/items?itemName=christian-kohler.path-intellisense) |
|||
- [npm Intellisense](https://marketplace.visualstudio.com/items?itemName=christian-kohler.npm-intellisense) |
|||
- [Angular 10 Snippets - TypeScript, Html, Angular Material, ngRx, RxJS & Flex Layout](https://marketplace.visualstudio.com/items?itemName=Mikael.Angular-BeastCode) |
|||
- [JavaScript (ES6) code snippets](https://marketplace.visualstudio.com/items?itemName=xabikos.JavaScriptSnippets) |
|||
- [Debugger for Chrome](https://marketplace.visualstudio.com/items?itemName=msjsdiag.debugger-for-chrome) |
|||
- [Git History](https://marketplace.visualstudio.com/items?itemName=donjayamanne.githistory) |
|||
- [indent-rainbow](https://marketplace.visualstudio.com/items?itemName=oderwat.indent-rainbow) |
|||
|
|||
## How to Start a New Angular Project |
|||
|
|||
You have multiple options to initiate a new Angular project that works with ABP: |
|||
|
|||
### 1. Using ABP CLI |
|||
|
|||
ABP CLI is probably the most convenient and flexible way to initiate an ABP solution with an Angular frontend. Simply [install the ABP CLI](../../CLI.md) and run the following command in your terminal: |
|||
|
|||
```shell |
|||
abp new MyCompanyName.MyProjectName -csf -u angular |
|||
``` |
|||
|
|||
> To see further options in the CLI, please visit the [CLI manual](../../CLI.md). |
|||
|
|||
This command will prepare a solution with an Angular and a .NET Core project in it. Please visit [Getting Started section](../../Getting-Started.md?UI=NG&DB=EF&Tiered=No#abp-cli-commands-options) for further instructions on how to set up the backend of your solution. |
|||
|
|||
To continue reading without checking other methods, visit [Angular project structure section](#angular-project-structure). |
|||
|
|||
### 2. Direct Download |
|||
|
|||
You may [download a solution scaffold directly on ABP.io](https://abp.io/get-started) if you are more comfortable with GUI or simply want to try ABP without installing the CLI. |
|||
|
|||
Please do the following: |
|||
|
|||
1. Click on the "DIRECT DOWNLOAD" tab. |
|||
2. Fill out the short form about your project. |
|||
3. Click on the "Create now" button. |
|||
|
|||
...and a customized download will start in a few seconds. |
|||
|
|||
To avoid IDE warnings, run `yarn` or `npm install` in the Angular root folder before you continue to the next section. It is not imperative but recommended. |
|||
|
|||
## Angular Project Structure |
|||
|
|||
After creating a solution, open its "angular" directory in your IDE. This is how the contents of the root folder looks like: |
|||
|
|||
<img alt="Angular project root folder structure" src="./images/quick-start---root-folder-structure.png" width="300px" style="max-width:100%"> |
|||
|
|||
Here is what these folders and files are for: |
|||
|
|||
- **.vscode** has extension recommendations in it. |
|||
- **e2e** is a separate app for possible end-to-end tests. |
|||
- **src** is where the source files for your application are placed. We will have a closer look in a minute. |
|||
- **.browserlistrc** helps [configuring browser compatibility of your Angular app](https://angular.io/guide/build#configuring-browser-compatibility). |
|||
- **.editorconfig** helps you have a shared coding style for separate editors and IDEs. Check [EditorConfig.org](https://editorconfig.org/) for details. |
|||
- **.gitignore** defined which files and folders should not be tracked by git. Check [git documentation](https://git-scm.com/docs/gitignore) for details. |
|||
- **.prettierrc** includes simple coding style choices for [Prettier](https://prettier.io/), an auto-formatter for TypeScript, HTML, CSS, and more. If you install recommended extensions to VS Code, you will never have to format your code anymore. |
|||
- **angular.json** is where Angular workspace is defined. It holds project configurations and workspace preferences. Please refer to [Angular workspace configuration](https://angular.io/guide/workspace-config) for details. |
|||
- **karma.conf.js** holds [Karma test runner](https://karma-runner.github.io/) configurations. |
|||
- **package.json** is where your [package dependencies](https://angular.io/guide/npm-packages) are listed. It also includes some useful scripts for developing, testing, and building your application. |
|||
- **README.md** includes some of Angular CLI command examples. You either have to install Angular CLI globally or run these commands starting with `yarn` or `npx` to make them work. |
|||
- **start.ps1** is a simple PowerShell script to install dependencies and start a [development server via Angular CLI](https://angular.io/cli/serve), but you probably will not need that after reading this document. |
|||
- **tsconfig.json** and all other [tsconfig files](https://angular.io/guide/typescript-configuration) in general, include some TypeScript and Angular compile options. |
|||
- **yarn.lock** enables installing consistent package versions across different devices so that working application build will not break because of a package update. Please read [Yarn documentation](https://classic.yarnpkg.com/en/docs/yarn-lock/) if you are interested in more information on the topic. If you have decided to use npm, please remove this file and keep the [package-lock.json](https://docs.npmjs.com/files/package-lock.json) instead. |
|||
|
|||
Now let us take a look at the contents of the source folder. |
|||
|
|||
<img alt="Angular project source folder structure" src="./images/quick-start---source-folder-structure.png" width="300px" style="max-width:100%"> |
|||
|
|||
- **app** is the main directory you put your application files in. Any module, component, directive, service, pipe, guard, interceptor, etc. should be placed here. You are free to choose any folder structure, but [organizing Angular applications based on modules](https://angular.io/guide/module-types) is generally a fine practice. |
|||
- **home** is a predefined module and acts as a welcome page. It also demonstrates how a feature-based folder structure may look like. More complex features will probably have sub-features, thus inner folders. You may change the home folder however you like. |
|||
- **shared** is spared for reusable code that works for several modules. Some, including yours truly, may disagree with using a single module for all shared code, so consider adding standalone sub-modules inside this folder instead of adding everything into **shared.module.ts**. |
|||
- **app-routing.module.ts** is where your top-level routes are defined. Angular is capable of [lazy loading feature modules](https://angular.io/guide/lazy-loading-ngmodules), so not all routes will be here. You may think of Angular routing as a tree and this file is the top of the tree. |
|||
- **app.component.ts** is essentially the top component that holds the dynamic application layout. |
|||
- **app.module.ts** is the [root module](https://angular.io/guide/bootstrapping) that includes information about how parts of your application are related and what to run at the initiation of your application. |
|||
- **route.provider.ts** is used for [modifying the menu](https://docs.abp.io/en/abp/latest/UI/Angular/Modifying-the-Menu). |
|||
- **assets** is for static files. A file (e.g. an image) placed in this folder will be available as is when the application is served. |
|||
- **environments** includes one file per environment configuration. There are two configurations by default, but you may always introduce another one. These files are directly referred to in _angular.json_ and help you have different builds and application variables. Please refer to [configuring Angular application environments](https://angular.io/guide/build#configuring-application-environments) for details. |
|||
- **index.html** is the HTML page served to visitors and will contain everything required to run your application. Servers should be configured to redirect every request to this page so that the Angular router can take over. Do not worry about how to add JavaScript and CSS files to it, because Angular CLI will do it automatically. |
|||
- **main.ts** bootstraps and configures Angular application to run in the browser. It is production-ready, so forget about it. |
|||
- **polyfill.ts** is where you can add polyfills if you want to [support legacy browsers](https://angular.io/guide/browser-support). |
|||
- **style.scss** is the default entry point for application styles. You can change this or add new entry points in _angular.json_. |
|||
- **test.ts** helps the unit test runner discover and bootstrap spec files. |
|||
|
|||
Phew! So many files, right? Yet, **most of them are typically not subject to change** or, even when they are so, the CLI tooling will do the job for you. The main focus should be on the app folder and its content. |
|||
|
|||
Next, we will take a look at the commands used to prepare, build, and serve our application. |
|||
|
|||
## How to Run the Angular Application |
|||
|
|||
Now that you know about the files and folders, we can get the application up and running. |
|||
|
|||
1. Make sure the [database migration is complete](../../Getting-Started?UI=NG&DB=EF&Tiered=No#create-the-database) and the [API is up and running](../../Getting-Started?UI=NG&DB=EF&Tiered=No#run-the-application). |
|||
2. Run `yarn` or `npm install` if you have not already. |
|||
3. Run `yarn start` or `npm start`. The first compilation may take a while. This will start a [live development server](#angular-live-development-server) and launch your default browser in the end. |
|||
4. Visit the browser page that opens after the compilation <sup id="a-certificate-error">[1](#f-certificate-error)</sup>. |
|||
|
|||
<img alt="New ABP Angular project home page" src="./images/quick-start---new-project-home-page.png" width="744px" style="max-width:100%"> |
|||
|
|||
You may modify the behavior of the **start script** (in the package.json file) by changing the parameters passed to the `ng serve` command. For instance, if you do not want a browser window to open next time you run the script, remove `--open` from the end of it. Please check [ng serve documentation](https://angular.io/cli/serve) for all available options. |
|||
|
|||
### Angular Live Development Server |
|||
|
|||
The development server of Angular is based on [Webpack DevServer](https://webpack.js.org/configuration/dev-server/). It tracks changes to source files and syncs the browser window after an incremental re-compilation every time <sup id="a-dev-server">[2](#f-dev-server)</sup> you make one. Your experience will be like this: |
|||
|
|||
<img alt="Angular Live Development Server compiles again on template change and removes a button from the page displayed by the browser." src="./images/quick-start---angular-live-development-server.gif" width="818px" style="max-width:100%"> |
|||
|
|||
Please keep in mind that you should not use this server in production. To provide the fastest experience, the compiler skips some heavy optimizations and the development server is simply not built for multiple clients. The next section will describe what to do. |
|||
|
|||
--- |
|||
|
|||
<img alt="Error caused by browser blocking access to backend" src="./images/quick-start---self-signed-certificate-error.png" width="400px" style="max-width:100%"> |
|||
|
|||
<sup id="f-certificate-error"><b>1</b></sup> _If you see the error above when you run the Angular app, your browser might be blocking access to the API because of the self-signed certificate. Visit that address and allow access to it (once). When you see the Swagger interface, you are good to go._ <sup>[↩](#a-certificate-error)</sup> |
|||
|
|||
<sup id="f-dev-server"><b>2</b></sup> _Sometimes, depending on the file changed, Webpack may miss the change and cannot reflect it in the browser. For example, tsconfig files are not being tracked. In such a case, please restart the development server._ <sup>[↩](#a-dev-server)</sup> |
|||
|
|||
--- |
|||
|
|||
## How to Build the Angular Application |
|||
|
|||
An Angular application can have multiple [build targets](https://angular.io/guide/glossary#target), i.e. **configurations in angular.json** which define how [Architect](https://angular.io/guide/glossary#architect) will build applications and libraries. Usually, each build configuration has a separate environment variable file. Currently, the project has two: One for development and one for production. |
|||
|
|||
```js |
|||
// this is what environment variables look like |
|||
// can be found at /src/environments/environment.ts |
|||
|
|||
import { Config } from '@abp/ng.core'; |
|||
|
|||
const baseUrl = 'http://localhost:4200'; |
|||
|
|||
export const environment = { |
|||
production: false, |
|||
application: { |
|||
baseUrl, |
|||
name: 'MyProjectName', |
|||
logoUrl: '', |
|||
}, |
|||
oAuthConfig: { |
|||
issuer: 'https://localhost:44381', |
|||
redirectUri: baseUrl, |
|||
clientId: 'MyProjectName_App', |
|||
responseType: 'code', |
|||
scope: 'offline_access MyProjectName', |
|||
}, |
|||
apis: { |
|||
default: { |
|||
url: 'https://localhost:44381', |
|||
rootNamespace: 'MyCompanyName.MyProjectName', |
|||
}, |
|||
}, |
|||
} as Config.Environment; |
|||
``` |
|||
|
|||
When you run the development server, variables defined in _environment.ts_ take effect. Similarly, in production mode, the default environment is replaced by _environment.prod.ts_ and completely different variables become effective. You may even [create a new build configuration](https://angular.io/guide/workspace-config#build-configs) and set [file replacements](https://angular.io/guide/build#configure-target-specific-file-replacements) to use a completely new environment. For now, we will start a production build: |
|||
|
|||
1. Open your terminal and navigate to the root Angular folder. |
|||
2. Run `yarn` or `npm install` if you have not installed dependencies already. |
|||
3. Run `yarn build:prod` or `npm run build:prod`. |
|||
|
|||
<img alt="Angular compiler optimizing the build using Terser" src="./images/quick-start---self-signed-certificate-error.png" width="400px" style="max-width:100%"> |
|||
|
|||
Depending on project size, the compilation may take a few minutes. When it is finished, the compiled output will be placed inside the _/dist_ folder. Voila! You have deployment-ready build artifacts. |
|||
|
|||
> The amount of optimization performed on the source is the main difference between a regular build and a production one. Production builds have a much smaller size and are more performant. |
|||
|
|||
## How to Deploy the Angular Application |
|||
|
|||
Angular web applications run on the browser and require no server except for a [static web server](https://developer.mozilla.org/en-US/docs/Learn/Common_questions/What_is_a_web_server) to deliver files to the client. To see that it works, please make sure the backend application is up and then run the following command in your terminal: |
|||
|
|||
```shell |
|||
# please replace MyProjectName with your project name |
|||
|
|||
npx servor dist/MyProjectName index.html 4200 --browse |
|||
``` |
|||
|
|||
This command will download and start a simple static server, a browser window at `http://localhost:4200` will open, and the compiled output of your project will be served. |
|||
|
|||
Of course, you need your application to run on an optimized web server and become available to everyone. This is quite straight-forward: |
|||
|
|||
1. Create a new static web server instance. You can use a service like [Azure App Service](https://azure.microsoft.com/tr-tr/services/app-service/web/), [Firebase](https://firebase.google.com/docs/hosting), [Netlify](https://www.netlify.com/), [Vercel](https://vercel.com/), or even [GitHub Pages](https://angular.io/guide/deployment#deploy-to-github-pages). Another option is maintaining own web server with [NGINX](https://www.nginx.com/), [IIS](https://www.iis.net/), [Apache HTTP Server](https://httpd.apache.org/), or equivalent. |
|||
2. Copy the files from `dist/MyProjectName` <sup id="a-dist-folder-name">[1](#f-dist-folder-name)</sup> to a publicly served destination on the server via CLI of the service provider, SSH, or FTP (whichever is available). This step would be defined as a job if you have a CI/CD flow. |
|||
3. [Configure the server](https://angular.io/guide/deployment#server-configuration) to redirect all requests to the _index.html_ file. Some services do that automatically. Others require you [to add a file to the bundle via assets](https://angular.io/guide/workspace-config#assets-configuration) which describes the server how to do the redirections. Occasionally, you may need to do manual configuration. |
|||
|
|||
In addition, you can [deploy your application to certain targets using the Angular CLI](https://angular.io/guide/deployment#automatic-deployment-with-the-cli). Here are some deploy targets: |
|||
|
|||
- [Azure](https://github.com/Azure/ng-deploy-azure#readme) |
|||
- [Firebase](https://github.com/angular/angularfire#readme) |
|||
- [Netlify](https://github.com/ngx-builders/netlify-builder#readme) |
|||
- [Vercel](https://github.com/vercel/ng-deploy-vercel#readme) |
|||
- [GitHub Pages](https://github.com/angular-schule/angular-cli-ghpages/#readme) |
|||
|
|||
--- |
|||
|
|||
<sup id="f-dist-folder-name"><b>1</b></sup> _The compiled output will be placed under `/dist` in a folder by the project name._ <sup>[↩](#a-dist-folder-name)</sup> |
|||
|
|||
--- |
|||
|
|||
## What's Next? |
|||
|
|||
- [Environment Variables](./Environment.md) |
|||
|
Before Width: | Height: | Size: 63 KiB After Width: | Height: | Size: 83 KiB |
|
After Width: | Height: | Size: 247 KiB |
|
After Width: | Height: | Size: 1.7 MiB |
|
After Width: | Height: | Size: 42 KiB |
|
After Width: | Height: | Size: 28 KiB |
|
After Width: | Height: | Size: 114 KiB |
|
After Width: | Height: | Size: 50 KiB |
|
After Width: | Height: | Size: 146 KiB |