diff --git a/.gitignore b/.gitignore index 3c5c4f89da..2f820efc4d 100644 --- a/.gitignore +++ b/.gitignore @@ -310,4 +310,7 @@ abp-build-config.json /templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Blazor/Pages/Test/ # Identity Server temp signature file -tempkey.jwk \ No newline at end of file +tempkey.jwk + +# ABP Analyzing files +*.abppkg.analyze.json \ No newline at end of file diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Account/Localization/Resources/FR.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Account/Localization/Resources/fr.json similarity index 89% rename from abp_io/AbpIoLocalization/AbpIoLocalization/Account/Localization/Resources/FR.json rename to abp_io/AbpIoLocalization/AbpIoLocalization/Account/Localization/Resources/fr.json index daab6ff118..5129f098e1 100644 --- a/abp_io/AbpIoLocalization/AbpIoLocalization/Account/Localization/Resources/FR.json +++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Account/Localization/Resources/fr.json @@ -5,7 +5,7 @@ "Welcome": "Bienvenue", "UseOneOfTheFollowingLinksToContinue": "Utilisez l'un des liens suivants pour continuer", "FrameworkHomePage": "Page d'accueil du framework", - "FrameworkDocumentation": "Documentation du cadre", + "FrameworkDocumentation": "Documentation du framework", "OfficialBlog": "Blog officiel", "CommercialHomePage": "Page d'accueil commerciale", "CommercialSupportWebSite": "Site Web de support commercial", diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Account/Localization/Resources/hi.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Account/Localization/Resources/hi.json new file mode 100644 index 0000000000..2029996445 --- /dev/null +++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Account/Localization/Resources/hi.json @@ -0,0 +1,14 @@ +{ + "culture": "hi", + "texts": { + "Account": "ABP खाता - लॉगिन और रजिस्टर | ABP.IO", + "Welcome": "स्वागत हे", + "UseOneOfTheFollowingLinksToContinue": "जारी रखने के लिए निम्न लिंक में से एक का उपयोग करें", + "FrameworkHomePage": "फ्रेमवर्क होम पेज", + "FrameworkDocumentation": "फ्रेमवर्क प्रलेखन", + "OfficialBlog": "आधिकारिक ब्लॉग", + "CommercialHomePage": "वाणिज्यिक मुख पृष्ठ", + "CommercialSupportWebSite": "वाणिज्यिक समर्थन वेब साइट", + "CommunityWebSite": "एबीपी सामुदायिक वेब साइट" + } +} \ No newline at end of file diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Account/Localization/Resources/it.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Account/Localization/Resources/it.json new file mode 100644 index 0000000000..6dada8fba7 --- /dev/null +++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Account/Localization/Resources/it.json @@ -0,0 +1,14 @@ +{ + "culture": "it", + "texts": { + "Account": "Account ABP - Accesso e registrazione | ABP.IO", + "Welcome": "benvenuto", + "UseOneOfTheFollowingLinksToContinue": "Usa uno dei seguenti link per continuare", + "FrameworkHomePage": "Home page del framework", + "FrameworkDocumentation": "Documentazione del framework", + "OfficialBlog": "Blog ufficiale", + "CommercialHomePage": "Home page commerciale", + "CommercialSupportWebSite": "Sito web di supporto commerciale", + "CommunityWebSite": "Sito web della comunità ABP" + } +} \ No newline at end of file diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Admin/Localization/Resources/FR.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Admin/Localization/Resources/fr.json similarity index 94% rename from abp_io/AbpIoLocalization/AbpIoLocalization/Admin/Localization/Resources/FR.json rename to abp_io/AbpIoLocalization/AbpIoLocalization/Admin/Localization/Resources/fr.json index 464566a6d9..2a2d8ba568 100644 --- a/abp_io/AbpIoLocalization/AbpIoLocalization/Admin/Localization/Resources/FR.json +++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Admin/Localization/Resources/fr.json @@ -10,7 +10,7 @@ "Permission:EnableSendEmail": "Activer l'envoi d'e-mail", "Permission:SendEmail": "Envoyer un e-mail", "Permission:NpmPackages": "Packages NPM", - "Permission:NugetPackages": "Nuget: formules de vacances", + "Permission:NugetPackages": "Packages Nuget", "Permission:Maintenance": "Maintenance", "Permission:Maintain": "Maintenir", "Permission:ClearCaches": "Effacer les caches", @@ -49,14 +49,14 @@ "NugetPackageTarget.ApplicationContracts": "Contrats d'application", "NugetPackageTarget.HttpApi": "Http Api", "NugetPackageTarget.HttpApiClient": "Client Api Http", - "NugetPackageTarget.Web": "la toile", + "NugetPackageTarget.Web": "Web", "NugetPackageTarget.EntityFrameworkCore": "DeleteAllEntityFramework Core", "NugetPackageTarget.MongoDB": "MongoDB", "Edit": "Éditer", "Delete": "Effacer", "Refresh": "Rafraîchir", "NpmPackages": "Packages NPM", - "NugetPackages": "Nuget: formules de vacances", + "NugetPackages": "Packages Nuget", "NpmPackageCount": "Nombre de packages NPM", "NugetPackageCount": "Nombre de paquets Nuget", "Module": "Modules", @@ -72,7 +72,7 @@ "Menu:NpmPackages": "Packages NPM", "Menu:Modules": "Modules", "Menu:Maintenance": "Maintenance", - "Menu:NugetPackages": "Nuget: formules de vacances", + "Menu:NugetPackages": "Packages Nuget", "CreateAnOrganization": "Créer une organisation", "Organizations": "Organisations", "LongName": "Nom long", @@ -92,13 +92,13 @@ "{0}WillBeRemovedFromDevelopers": "{0} Sera supprimé des développeurs, confirmez-vous?", "{0}WillBeRemovedFromOwners": "{0} Sera supprimé des propriétaires, confirmez-vous?", "{0}WillBeRemovedFromMembers": "{0} Sera supprimé des membres, confirmez-vous?", - "Computers": "Des ordinateurs", + "Computers": "Ordinateurs", "UniqueComputerId": "ID d'ordinateur unique", "LastSeenDate": "Date de la dernière consultation", "{0}Computer{1}WillBeRemovedFromRecords": "L'ordinateur de {0} ({1}) sera supprimé des enregistrements", "OrganizationDeletionWarningMessage": "L'organisation sera supprimée", "DeletingLastOwnerWarningMessage": "Une organisation doit avoir au moins un propriétaire! Par conséquent, vous ne pouvez pas supprimer ce propriétaire", - "This{0}AlreadyExistInThisOrganization": "Cela {0} existe déjà dans cette organisation", + "This{0}AlreadyExistInThisOrganization": "Ce {0} existe déjà dans cette organisation", "AreYouSureYouWantToDeleteAllComputers": "Voulez-vous vraiment supprimer tous les ordinateurs?", "DeleteAll": "Tout supprimer", "DoYouWantToCreateNewUser": "Voulez-vous créer un nouvel utilisateur?", @@ -119,7 +119,7 @@ "Member": "Membre", "PurchaseOrderNo": "Bon de commande non", "QuotationDate": "Date du devis", - "CompanyName": "Nom de la compagnie", + "CompanyName": "Nom de la société", "CompanyAddress": "Adresse de la société", "Price": "Prix", "DiscountText": "Texte de remise", @@ -138,7 +138,7 @@ "AddProduct": "Ajouter un produit", "AddProductWarning": "Vous devez ajouter un produit!", "TotalPrice": "Prix total", - "Generate": "produire", + "Generate": "Générer", "MissingQuantityField": "Le champ de quantité est obligatoire!", "MissingPriceField": "Le champ Prix est obligatoire!", "CodeUsageStatus": "Statut", @@ -170,11 +170,11 @@ "UnlimitedQuestionCount": "Nombre de questions illimité", "Notes": "Remarques", "Menu:Community": "Communauté", - "Menu:Articles": "Des articles", + "Menu:Articles": "Articles", "Wait": "Attendez", "Approve": "Approuver", "Reject": "Rejeter", - "Details": "Des détails", + "Details": "Détails", "Url": "URL", "Title": "Titre", "ContentSource": "Source du contenu", @@ -228,7 +228,7 @@ "Username": "Nom d'utilisateur", "Tool": "Outil", "Command": "Commander", - "UiFramework": "Cadre de l'interface utilisateur", + "UiFramework": "Framework de l'interface utilisateur", "Options": "Options", "CliAnalytics": "Cli Analytics", "Permission:CliAnalyticses": "Analyses Cli", @@ -239,13 +239,13 @@ "LicensePublicKey": "Clé publique de licence", "ApiKey": "Clé d'API NuGet", "ShowInvoiceRequestsOfOrganization": "Demandes de factures", - "ShowQuestionsOfOrganization": "Des questions", + "ShowQuestionsOfOrganization": "Questions", "Question": "Question", "Open": "Ouvert", - "Questions": "Des questions", + "Questions": "Questions", "InvoiceRequests": "Demandes de factures", "Address": "Adresse", - "TaxNo": "Impôt non", + "TaxNo": "Numéro de taxe", "Permission:InvoiceRequest": "Demande de facturation", "Permission:Question": "Question", "AddNoteSuccessMessage": "Note ajoutée avec succès", @@ -258,7 +258,7 @@ "Enum:EntityChangeType:0": "Créé", "Enum:EntityChangeType:1": "Mise à jour", "Enum:EntityChangeType:2": "Supprimé", - "TenantId": "ID du locataire", + "TenantId": "ID du souscrivant", "ChangeTime": "Changer le temps", "EntityTypeFullName": "Nom complet du type d'entité", "AuditLogsFor{0}Organization": "Journaux d'audit pour l'organisation \"{0}\"", diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Admin/Localization/Resources/hi.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Admin/Localization/Resources/hi.json new file mode 100644 index 0000000000..7b0f4ad205 --- /dev/null +++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Admin/Localization/Resources/hi.json @@ -0,0 +1,282 @@ +{ + "culture": "hi", + "texts": { + "Permission:Organizations": "संगठनों", + "Permission:Manage": "संगठनों को प्रबंधित करें", + "Permission:DiscountRequests": "छूट का अनुरोध", + "Permission:DiscountManage": "डिस्काउंट अनुरोध प्रबंधित करें", + "Permission:Disable": "अक्षम", + "Permission:Enable": "सक्षम", + "Permission:EnableSendEmail": "ईमेल सक्षम करें", + "Permission:SendEmail": "ईमेल भेजें", + "Permission:NpmPackages": "एनपीएम पैकेज", + "Permission:NugetPackages": "नगेट संकुल", + "Permission:Maintenance": "रखरखाव", + "Permission:Maintain": "बनाए रखें", + "Permission:ClearCaches": "साफ कैश", + "Permission:Modules": "मॉड्यूल", + "Permission:Packages": "संकुल", + "Permission:Edit": "संपादित करें", + "Permission:Delete": "हटाएं", + "Permission:Create": "सृजन करना", + "Permission:Accounting": "लेखांकन", + "Permission:Accounting:Quotation": "उद्धरण", + "Permission:Accounting:Invoice": "बीजक", + "Menu:Organizations": "संगठनों", + "Menu:Accounting": "लेखांकन", + "Menu:Packages": "संकुल", + "Menu:DiscountRequests": "छूट का अनुरोध", + "NpmPackageDeletionWarningMessage": "यह NPM पैकेज हटा दिया जाएगा। क्या आप इसकी पुष्टि करते हैं?", + "NugetPackageDeletionWarningMessage": "यह नुगेट पैकेज हटा दिया जाएगा। क्या आप इसकी पुष्टि करते हैं?", + "ModuleDeletionWarningMessage": "यह मॉड्यूल हटा दिया जाएगा। क्या आप इसकी पुष्टि करते हैं?", + "Name": "नाम", + "DisplayName": "प्रदर्शित होने वाला नाम", + "ShortDescription": "संक्षिप्त वर्णन", + "NameFilter": "नाम", + "CreationTime": "रचना समय", + "IsPro": "समर्थक है", + "IsFreeToActiveLicenseOwners": "मालिकों को लाइसेंस देना मुफ्त", + "ShowOnModuleList": "मॉड्यूल सूची पर दिखाएं", + "EfCoreConfigureMethodName": "विधि नाम कॉन्फ़िगर करें", + "IsProFilter": "समर्थक है", + "ApplicationType": "आवेदन का प्रकार", + "Target": "लक्ष्य", + "TargetFilter": "लक्ष्य", + "ModuleClass": "मॉड्यूल वर्ग", + "NugetPackageTarget.DomainShared": "डोमेन साझा किया गया", + "NugetPackageTarget.Domain": "डोमेन", + "NugetPackageTarget.Application": "आवेदन", + "NugetPackageTarget.ApplicationContracts": "आवेदन संविदा", + "NugetPackageTarget.HttpApi": "Http Api", + "NugetPackageTarget.HttpApiClient": "Http Api क्लाइंट", + "NugetPackageTarget.Web": "वेब", + "NugetPackageTarget.EntityFrameworkCore": "DeleteAllEntityFramework Core", + "NugetPackageTarget.MongoDB": "MongoDB", + "Edit": "संपादित करें", + "Delete": "हटाएं", + "Refresh": "ताज़ा करना", + "NpmPackages": "एनपीएम पैकेज", + "NugetPackages": "नगेट संकुल", + "NpmPackageCount": "एनपीएम पैकेज की गणना", + "NugetPackageCount": "नगेट पैकेज गणना", + "Module": "मॉड्यूल", + "ModuleInfo": "मॉड्यूल जानकारी", + "CreateANpmPackage": "एक एनपीएम पैकेज बनाएँ", + "CreateAModule": "एक मॉड्यूल बनाएँ", + "CreateANugetPackage": "एक Nuget पैकेज बनाएँ", + "AddNew": "नया जोड़ें", + "PackageAlreadyExist{0}": "\"{0}\" पैकेज पहले से ही जोड़ा गया है।", + "ModuleAlreadyExist{0}": "\"{0}\" मॉड्यूल पहले से ही जोड़ा गया है।", + "ClearCache": "कैश को साफ़ करें", + "SuccessfullyCleared": "सफलतापूर्वक साफ़ हो गया", + "Menu:NpmPackages": "एनपीएम पैकेज", + "Menu:Modules": "मॉड्यूल", + "Menu:Maintenance": "रखरखाव", + "Menu:NugetPackages": "नगेट संकुल", + "CreateAnOrganization": "एक संगठन बनाएं", + "Organizations": "संगठनों", + "LongName": "लंबा नाम", + "LicenseType": "लाइसेंस के प्रकार", + "MissingLicenseTypeField": "लाइसेंस प्रकार क्षेत्र की आवश्यकता है!", + "LicenseStartTime": "लाइसेंस शुरू होने का समय", + "LicenseEndTime": "लाइसेंस समाप्ति का समय", + "AllowedDeveloperCount": "अनुमत डेवलपर गणना", + "UserNameOrEmailAddress": "उपयोगकर्ता का नाम या ईमेल पता", + "AddOwner": "मालिक जोड़ें", + "UserName": "उपयोगकर्ता नाम", + "Email": "ईमेल", + "Developers": "डेवलपर्स", + "AddDeveloper": "डेवलपर जोड़ें", + "Create": "सृजन करना", + "UserNotFound": "उपयोगकर्ता नहीं मिला", + "{0}WillBeRemovedFromDevelopers": "{0} डेवलपर्स से हटा दिया जाएगा, क्या आप पुष्टि करते हैं?", + "{0}WillBeRemovedFromOwners": "{0} मालिकों से हटा दिया जाएगा, क्या आप पुष्टि करते हैं?", + "{0}WillBeRemovedFromMembers": "{0} सदस्यों से हटा दिया जाएगा, क्या आप पुष्टि करते हैं?", + "Computers": "कंप्यूटर", + "UniqueComputerId": "यूनिक कंप्यूटर आई.डी.", + "LastSeenDate": "अंतिम बार देखी गई तारीख", + "{0}Computer{1}WillBeRemovedFromRecords": "{0} ({1}) का कंप्यूटर रिकॉर्ड से हटा दिया जाएगा", + "OrganizationDeletionWarningMessage": "संगठन को हटा दिया जाएगा", + "DeletingLastOwnerWarningMessage": "एक संगठन में कम से कम एक मालिक होना चाहिए! इसलिए आप इस स्वामी को नहीं निकाल सकते", + "This{0}AlreadyExistInThisOrganization": "यह {0} इस संगठन में पहले से मौजूद है", + "AreYouSureYouWantToDeleteAllComputers": "क्या आप वाकई सभी कंप्यूटर हटाना चाहते हैं?", + "DeleteAll": "सभी हटा दो", + "DoYouWantToCreateNewUser": "क्या आप नया उपयोगकर्ता बनाना चाहते हैं?", + "MasterModules": "मास्टर मॉड्यूल", + "OrganizationName": "संगठन का नाम", + "CreationDate": "निर्माण तिथि", + "LicenseStartDate": "लाइसेंस शुरू होने की तारीख", + "LicenseEndDate": "लाइसेंस की अंतिम तिथि", + "OrganizationNamePlaceholder": "संगठन का नाम...", + "TotalQuestionCountPlaceholder": "कुल प्रश्न संख्या ...", + "RemainingQuestionCountPlaceholder": "शेष प्रश्न गणना ...", + "LicenseTypePlaceholder": "लाइसेंस के प्रकार...", + "CreationDatePlaceholder": "निर्माण तिथि...", + "LicenseStartDatePlaceholder": "लाइसेंस शुरू होने की तारीख ...", + "LicenseEndDatePlaceholder": "लाइसेंस की अंतिम तिथि ...", + "UsernameOrEmail": "उपयोगकर्ता का नाम या ईमेल", + "UsernameOrEmailPlaceholder": "उपयोगकर्ता का नाम या ईमेल...", + "Member": "सदस्य", + "PurchaseOrderNo": "खरीद आदेश ्संक्या", + "QuotationDate": "बोली की तारीख", + "CompanyName": "कंपनी का नाम", + "CompanyAddress": "कम्पनी का पता", + "Price": "कीमत", + "DiscountText": "डिस्काउंट पाठ", + "DiscountQuantity": "छूट मात्रा", + "DiscountPrice": "डिस्काउंट कीमत", + "Quotation": "उद्धरण", + "ExtraText": "अतिरिक्त पाठ", + "ExtraAmount": "अतिरिक्त राशि", + "DownloadQuotation": "उद्धरण डाउनलोड करें", + "Invoice": "बीजक", + "TaxNumber": "कर संख्या", + "InvoiceNumber": "बीजक संख्या", + "InvoiceDate": "चालान की तारीख", + "InvoiceNote": "चालान नोट", + "Quantity": "मात्रा", + "AddProduct": "उत्पाद जोड़ें", + "AddProductWarning": "आपको उत्पाद जोड़ने की आवश्यकता है!", + "TotalPrice": "कुल कीमत", + "Generate": "उत्पन्न", + "MissingQuantityField": "मात्रा फ़ील्ड आवश्यक है!", + "MissingPriceField": "मूल्य क्षेत्र की आवश्यकता है!", + "CodeUsageStatus": "स्थिति", + "Country": "देश", + "DeveloperCount": "डेवलपर गणना", + "RequestCode": "अनुरोध कोड", + "WebSite": "वेबसाइट", + "GithubUsername": "Github उपयोगकर्ता नाम", + "PhoneNumber": "फ़ोन नंबर", + "ProjectDescription": "परियोजना विवरण", + "Referrer": "संदर्भ", + "DiscountRequests": "छूट का अनुरोध", + "Copylink": "प्रतिरूप जोड़ना", + "Disable": "अक्षम", + "Enable": "सक्षम", + "EnableSendEmail": "ईमेल सक्षम करें", + "SendEmail": "ईमेल भेजें", + "SuccessfullyDisabled": "सफलतापूर्वक अक्षम किया गया", + "SuccessfullyEnabled": "सफलतापूर्वक सक्षम किया गया", + "EmailSent": "ईमेल भेजा", + "SuccessfullySent": "सफलतापूर्वक भेजा", + "SuccessfullyDeleted": "सफलतापूर्वक हटा दिया गया", + "DiscountRequestDeletionWarningMessage": "छूट अनुरोध हटा दिया जाएगा", + "BusinessType": "व्यापार के प्रकार", + "TotalQuestionCount": "कुल प्रश्न संख्या", + "RemainingQuestionCount": "शेष प्रश्न गणना", + "TotalQuestionMustBeGreaterWarningMessage": "TotalQuestionCount RemainingQuestionCount से अधिक होना चाहिए!", + "QuestionCountsMustBeGreaterThanZero": "TotalQuestionCount और RemainingQuestionCount शून्य या शून्य से अधिक होना चाहिए!", + "UnlimitedQuestionCount": "असीमित प्रश्न गणना", + "Notes": "टिप्पणियाँ", + "Menu:Community": "समुदाय", + "Menu:Articles": "सामग्री", + "Wait": "रुको", + "Approve": "मंजूर", + "Reject": "अस्वीकार", + "Details": "विवरण", + "Url": "यूआरएल", + "Title": "शीर्षक", + "ContentSource": "विषय - वस्तु का स्रोत", + "Status": "स्थिति", + "ReadArticle": "लेख पढ़ें", + "ArticleHasBeenWaiting": "लेख की प्रतीक्षा रही", + "ArticleHasBeenApproved": "अनुच्छेद स्वीकृत किया गया है", + "ArticleHasBeenRejected": "अनुच्छेद अस्वीकार कर दिया गया है", + "Permission:Community": "समुदाय", + "Permission:CommunityArticle": "लेख", + "Link": "संपर्क", + "Enum:ContentSource:0": "Github", + "Enum:ContentSource:1": "बाहरी", + "Enum:Status:0": "इंतज़ार कर रही", + "Enum:Status:1": "अस्वीकृत", + "Enum:Status:2": "मंजूर की", + "Summary": "सारांश", + "AuthorName": "लेखक का नाम", + "CoverImage": "कवर छवि", + "RemoveCacheConfirmationMessage": "क्या आप वाकई \"{0}\" लेख के लिए कैश निकालना चाहते हैं?", + "SuccessfullyRemoved": "सफलतापूर्वक साफ़ हो गया", + "RemoveCache": "कैश निकालें", + "Language": "भाषा: हिन्दी", + "Optional": "ऐच्छिक", + "CreateArticleLanguageInfo": "वह भाषा जिसमें पद लिखा जाता है", + "Enum:ContentSource:2": "वीडियो पोस्ट", + "VideoPreview": "वीडियो पूर्वावलोकन", + "VideoPreviewErrorMessage": "दिया गया वीडियो url Youtube से पुनः प्राप्त नहीं कर सका। यह वीडियो निजी होने के कारण हो सकता है या दिया गया URL उपलब्ध नहीं है।", + "DeleteCoverImage": "कवर छवि हटाएं", + "DeleteCoverImageConfirmationMessage": "क्या आप वाकई \"{0}\" के लिए कवर छवि को हटाना चाहते हैं?", + "DeleteCoverImageSuccessMessage": "कवर छवि सफलतापूर्वक हटा दी गई", + "PaymentsOf": "के भुगतान", + "ShowPaymentsOfOrganization": "भुगतान", + "Date": "तारीख", + "Products": "उत्पादों", + "TotalAmount": "कुल रकम", + "Currency": "मुद्रा", + "Gateway": "द्वार", + "State": "राज्य", + "FailReason": "विफल कारण", + "ReIndexAllPosts": "सभी पदों को फिर से लिखना", + "ReIndexAllPostsConfirmationMessage": "क्या आप वाकई सभी पदों को पुनः प्राप्त करना चाहते हैं?", + "SuccessfullyReIndexAllPosts": "सभी पदों को सफलतापूर्वक रीइंसेक्स किया गया है।", + "Permission:FullSearch": "पूरा पाठ खोजें", + "Menu:CliAnalytics": "Cli Analytics", + "TemplateName": "टेम्पलेट नाम", + "TemplateVersion": "टेम्पलेट संस्करण", + "DatabaseProvider": "डेटाबेस प्रदाता", + "IsTiered": "तीयर है", + "ProjectName": "परियोजना का नाम", + "Username": "उपयोगकर्ता नाम", + "Tool": "साधन", + "Command": "आदेश", + "UiFramework": "उई ढांचा", + "Options": "विकल्प", + "CliAnalytics": "Cli Analytics", + "Permission:CliAnalyticses": "क्ली एनालिटिक्स", + "Permission:CliAnalytics": "Cli Analytics", + "Search": "खोज", + "ClearFilter": "स्पष्ट निस्यंदक", + "LicensePrivateKey": "लाइसेंस निजी कुंजी", + "LicensePublicKey": "लाइसेंस सार्वजनिक कुंजी", + "ApiKey": "NuGet एपीआई कुंजी", + "ShowInvoiceRequestsOfOrganization": "चालान अनुरोध", + "ShowQuestionsOfOrganization": "प्रशन", + "Question": "सवाल", + "Open": "खुला हुआ", + "Questions": "प्रशन", + "InvoiceRequests": "चालान अनुरोध", + "Address": "पता", + "TaxNo": "टैक्स संख्या", + "Permission:InvoiceRequest": "बिल के लिए अनुरोध", + "Permission:Question": "सवाल", + "AddNoteSuccessMessage": "नोट सफलतापूर्वक जोड़ा गया", + "NameSurname": "नाम सरनेम", + "Note": "ध्यान दें", + "Add": "जोड़ना", + "ProjectDownloads": "प्रोजेक्ट डाउनलोड", + "ShowProjectDownloadsOfOrganization": "प्रोजेक्ट डाउनलोड", + "ShowAuditLogsOfOrganization": "ऑडिट लॉग", + "Enum:EntityChangeType:0": "बनाया था", + "Enum:EntityChangeType:1": "अद्यतन", + "Enum:EntityChangeType:2": "हटाए गए", + "TenantId": "किरायेदार आईडी", + "ChangeTime": "समय परिवर्तन करें", + "EntityTypeFullName": "संपूर्ण प्रकार पूर्ण नाम", + "AuditLogsFor{0}Organization": "\"{0}\" संगठन के लिए ऑडिट लॉग", + "Permission:EntityChange": "इकाई परिवर्तन", + "Permission:ProjectDownload": "प्रोजेक्ट डाउनलोड", + "Permission:PaymentRequest": "भुगतान अनुरोध", + "CreatorEmailAddress": "निर्माता का ईमेल पता", + "EmailSendDate": "ईमेल भेजने की तारीख", + "PaymentRequestsFor{0}Organization": "\"{0}\" संगठन के लिए भुगतान अनुरोध", + "PaymentDetails": "भुगतान विवरण", + "PaymentProduct": "भुगतान उत्पाद", + "ProductName": "उत्पाद का नाम", + "Code": "कोड", + "GenerateInvoice": "आनंद उत्पन्न करें", + "ExportOrganizationsToExcel": "एक्सेल में भेजे", + "ThisExtensionIsNotAllowed": "इस एक्सटेंशन की अनुमति नहीं है।", + "TheFileIsTooLarge": "फ़ाइल बहुत बड़ी है!", + "ArticleDeletionConfirmationMessage": "क्या आप वाकई इस लेख को हटाना चाहते हैं?", + "ChooseCoverImage": "कवर छवि चुनें ..." + } +} \ No newline at end of file diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Admin/Localization/Resources/it.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Admin/Localization/Resources/it.json new file mode 100644 index 0000000000..2aaacd7b86 --- /dev/null +++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Admin/Localization/Resources/it.json @@ -0,0 +1,282 @@ +{ + "culture": "it", + "texts": { + "Permission:Organizations": "Organizzazioni", + "Permission:Manage": "Gestisci organizzazioni", + "Permission:DiscountRequests": "Richieste di sconto", + "Permission:DiscountManage": "Gestisci le richieste di sconto", + "Permission:Disable": "disattivare", + "Permission:Enable": "Abilitare", + "Permission:EnableSendEmail": "Abilita Invia e-mail", + "Permission:SendEmail": "Invia una email", + "Permission:NpmPackages": "Pacchetti NPM", + "Permission:NugetPackages": "Pacchetti Nuget", + "Permission:Maintenance": "Manutenzione", + "Permission:Maintain": "Mantenere", + "Permission:ClearCaches": "Cancella cache", + "Permission:Modules": "Moduli", + "Permission:Packages": "Pacchi", + "Permission:Edit": "modificare", + "Permission:Delete": "Elimina", + "Permission:Create": "Creare", + "Permission:Accounting": "Contabilità", + "Permission:Accounting:Quotation": "Quotazione", + "Permission:Accounting:Invoice": "Fattura", + "Menu:Organizations": "Organizzazioni", + "Menu:Accounting": "Contabilità", + "Menu:Packages": "Pacchi", + "Menu:DiscountRequests": "Richieste di sconto", + "NpmPackageDeletionWarningMessage": "Questo pacchetto NPM verrà eliminato. Lo confermi?", + "NugetPackageDeletionWarningMessage": "Questo pacchetto Nuget verrà eliminato. Lo confermi?", + "ModuleDeletionWarningMessage": "Questo modulo verrà eliminato. Lo confermi?", + "Name": "Nome", + "DisplayName": "Nome da visualizzare", + "ShortDescription": "Breve descrizione", + "NameFilter": "Nome", + "CreationTime": "Tempo di creazione", + "IsPro": "È pro", + "IsFreeToActiveLicenseOwners": "Gratuito per i proprietari di licenze", + "ShowOnModuleList": "Mostra nell'elenco dei moduli", + "EfCoreConfigureMethodName": "Configurare il nome del metodo", + "IsProFilter": "È pro", + "ApplicationType": "Tipo di applicazione", + "Target": "Bersaglio", + "TargetFilter": "Bersaglio", + "ModuleClass": "Classe del modulo", + "NugetPackageTarget.DomainShared": "Dominio condiviso", + "NugetPackageTarget.Domain": "Dominio", + "NugetPackageTarget.Application": "Applicazione", + "NugetPackageTarget.ApplicationContracts": "Contratti applicativi", + "NugetPackageTarget.HttpApi": "Http Api", + "NugetPackageTarget.HttpApiClient": "Client API HTTP", + "NugetPackageTarget.Web": "ragnatela", + "NugetPackageTarget.EntityFrameworkCore": "DeleteAllEntityFramework Core", + "NugetPackageTarget.MongoDB": "MongoDB", + "Edit": "modificare", + "Delete": "Elimina", + "Refresh": "ricaricare", + "NpmPackages": "Pacchetti NPM", + "NugetPackages": "Pacchetti Nuget", + "NpmPackageCount": "Conteggio pacchetti NPM", + "NugetPackageCount": "Conteggio pacchetti Nuget", + "Module": "Moduli", + "ModuleInfo": "Informazioni sul modulo", + "CreateANpmPackage": "Crea un pacchetto NPM", + "CreateAModule": "Crea un modulo", + "CreateANugetPackage": "Crea un pacchetto Nuget", + "AddNew": "Aggiungere nuova", + "PackageAlreadyExist{0}": "Il pacchetto \"{0}\" è già aggiunto.", + "ModuleAlreadyExist{0}": "Il modulo \"{0}\" è già aggiunto.", + "ClearCache": "Cancella cache", + "SuccessfullyCleared": "Cancellato con successo", + "Menu:NpmPackages": "Pacchetti NPM", + "Menu:Modules": "Moduli", + "Menu:Maintenance": "Manutenzione", + "Menu:NugetPackages": "Pacchetti Nuget", + "CreateAnOrganization": "Crea un'organizzazione", + "Organizations": "Organizzazioni", + "LongName": "Nome lungo", + "LicenseType": "Tipo di licenza", + "MissingLicenseTypeField": "Il campo del tipo di licenza è obbligatorio!", + "LicenseStartTime": "Ora di inizio della licenza", + "LicenseEndTime": "Ora di fine della licenza", + "AllowedDeveloperCount": "Conteggio sviluppatori consentito", + "UserNameOrEmailAddress": "Username o Indirizzo Email", + "AddOwner": "Aggiungi proprietario", + "UserName": "Nome utente", + "Email": "E-mail", + "Developers": "Sviluppatori", + "AddDeveloper": "Aggiungi sviluppatore", + "Create": "Creare", + "UserNotFound": "Utente non trovato", + "{0}WillBeRemovedFromDevelopers": "{0} Verrà rimosso dagli sviluppatori, confermi?", + "{0}WillBeRemovedFromOwners": "{0} Verrà rimosso dai proprietari, confermi?", + "{0}WillBeRemovedFromMembers": "{0} Verrà rimosso dai membri, confermi?", + "Computers": "Computer", + "UniqueComputerId": "ID computer univoco", + "LastSeenDate": "Data dell'ultimo accesso", + "{0}Computer{1}WillBeRemovedFromRecords": "Il computer di {0} ({1}) verrà rimosso dai record", + "OrganizationDeletionWarningMessage": "L'organizzazione verrà eliminata", + "DeletingLastOwnerWarningMessage": "Un'organizzazione deve avere almeno un proprietario! Pertanto non puoi rimuovere questo proprietario", + "This{0}AlreadyExistInThisOrganization": "Questo {0} esiste già in questa organizzazione", + "AreYouSureYouWantToDeleteAllComputers": "Sei sicuro di voler eliminare tutti i computer?", + "DeleteAll": "Cancella tutto", + "DoYouWantToCreateNewUser": "Vuoi creare un nuovo utente?", + "MasterModules": "Moduli master", + "OrganizationName": "Nome dell'organizzazione", + "CreationDate": "Data di creazione", + "LicenseStartDate": "Data di inizio della licenza", + "LicenseEndDate": "Data di fine della licenza", + "OrganizationNamePlaceholder": "Nome dell'organizzazione...", + "TotalQuestionCountPlaceholder": "Conteggio totale delle domande ...", + "RemainingQuestionCountPlaceholder": "Numero di domande rimanenti ...", + "LicenseTypePlaceholder": "Tipo di licenza...", + "CreationDatePlaceholder": "Data di creazione...", + "LicenseStartDatePlaceholder": "Data di inizio della licenza ...", + "LicenseEndDatePlaceholder": "Data di fine della licenza ...", + "UsernameOrEmail": "Nome utente o email", + "UsernameOrEmailPlaceholder": "Nome utente o email...", + "Member": "Membro", + "PurchaseOrderNo": "Ordine d'Acquisto N °", + "QuotationDate": "Data di quotazione", + "CompanyName": "Nome della ditta", + "CompanyAddress": "Indirizzo aziendale", + "Price": "Prezzo", + "DiscountText": "Testo di sconto", + "DiscountQuantity": "Quantità di sconto", + "DiscountPrice": "Prezzo scontato", + "Quotation": "Quotazione", + "ExtraText": "Testo extra", + "ExtraAmount": "Importo extra", + "DownloadQuotation": "Scarica preventivo", + "Invoice": "Fattura", + "TaxNumber": "Codice fiscale", + "InvoiceNumber": "Numero di fattura", + "InvoiceDate": "Data fattura", + "InvoiceNote": "Nota fattura", + "Quantity": "Quantità", + "AddProduct": "Aggiungi prodotto", + "AddProductWarning": "Devi aggiungere il prodotto!", + "TotalPrice": "Prezzo totale", + "Generate": "creare", + "MissingQuantityField": "Il campo della quantità è obbligatorio!", + "MissingPriceField": "Il campo Prezzo è obbligatorio!", + "CodeUsageStatus": "Stato", + "Country": "Nazione", + "DeveloperCount": "Conteggio sviluppatori", + "RequestCode": "Codice richiesto", + "WebSite": "Sito web", + "GithubUsername": "Nome utente GitHub", + "PhoneNumber": "Numero di telefono", + "ProjectDescription": "descrizione del progetto", + "Referrer": "Referrer", + "DiscountRequests": "Richiesta di sconto", + "Copylink": "Copia link", + "Disable": "disattivare", + "Enable": "Abilitare", + "EnableSendEmail": "Abilita Invia e-mail", + "SendEmail": "Invia una email", + "SuccessfullyDisabled": "Disabilitato con successo", + "SuccessfullyEnabled": "Abilitato con successo", + "EmailSent": "Email inviata", + "SuccessfullySent": "Inviato con successo", + "SuccessfullyDeleted": "Eliminato con successo", + "DiscountRequestDeletionWarningMessage": "La richiesta di sconto verrà eliminata", + "BusinessType": "tipo di affari", + "TotalQuestionCount": "Conteggio totale delle domande", + "RemainingQuestionCount": "Numero di domande rimanenti", + "TotalQuestionMustBeGreaterWarningMessage": "TotalQuestionCount deve essere maggiore di RemainingQuestionCount!", + "QuestionCountsMustBeGreaterThanZero": "TotalQuestionCount e RemainingQuestionCount devono essere zero o maggiori di zero!", + "UnlimitedQuestionCount": "Conteggio illimitato delle domande", + "Notes": "Appunti", + "Menu:Community": "Comunità", + "Menu:Articles": "Articoli", + "Wait": "Aspettare", + "Approve": "Approvare", + "Reject": "Rifiutare", + "Details": "Dettagli", + "Url": "Url", + "Title": "Titolo", + "ContentSource": "Fonte di contenuto", + "Status": "Stato", + "ReadArticle": "Leggi l'articolo", + "ArticleHasBeenWaiting": "L'articolo è stato in attesa", + "ArticleHasBeenApproved": "L'articolo è stato approvato", + "ArticleHasBeenRejected": "L'articolo è stato respinto", + "Permission:Community": "Comunità", + "Permission:CommunityArticle": "Articolo", + "Link": "Link", + "Enum:ContentSource:0": "Github", + "Enum:ContentSource:1": "Esterno", + "Enum:Status:0": "In attesa", + "Enum:Status:1": "Respinto", + "Enum:Status:2": "Approvato", + "Summary": "Sommario", + "AuthorName": "Nome dell'autore", + "CoverImage": "Immagine di copertina", + "RemoveCacheConfirmationMessage": "Sei sicuro di aver rimosso la cache per l'articolo \"{0}\"?", + "SuccessfullyRemoved": "Cancellato con successo", + "RemoveCache": "Rimuovi cache", + "Language": "linguaggio", + "Optional": "Opzionale", + "CreateArticleLanguageInfo": "La lingua in cui è scritto il post", + "Enum:ContentSource:2": "Post video", + "VideoPreview": "Anteprima video", + "VideoPreviewErrorMessage": "Impossibile recuperare l'URL del video da Youtube. Ciò può essere causato dal fatto che il video è privato o l'URL fornito non è disponibile.", + "DeleteCoverImage": "Elimina immagine di copertina", + "DeleteCoverImageConfirmationMessage": "Sei sicuro di voler eliminare l'immagine di copertina per \"{0}\"?", + "DeleteCoverImageSuccessMessage": "Immagine di copertina eliminata con successo", + "PaymentsOf": "Pagamenti di", + "ShowPaymentsOfOrganization": "Pagamenti", + "Date": "Data", + "Products": "Prodotti", + "TotalAmount": "Importo totale", + "Currency": "Moneta", + "Gateway": "Gateway", + "State": "Stato", + "FailReason": "Motivo fallito", + "ReIndexAllPosts": "Reindicizza tutti i post", + "ReIndexAllPostsConfirmationMessage": "Sei sicuro di voler reindicizzare tutti i post?", + "SuccessfullyReIndexAllPosts": "Tutti i post sono stati reindicizzati con successo.", + "Permission:FullSearch": "Ricerca nel testo completo", + "Menu:CliAnalytics": "Cli Analytics", + "TemplateName": "Nome modello", + "TemplateVersion": "Versione modello", + "DatabaseProvider": "Provider di database", + "IsTiered": "È a livelli", + "ProjectName": "Nome del progetto", + "Username": "Nome utente", + "Tool": "Attrezzo", + "Command": "Comando", + "UiFramework": "Framework dell'interfaccia utente", + "Options": "Opzioni", + "CliAnalytics": "Cli Analytics", + "Permission:CliAnalyticses": "Cli Analyticses", + "Permission:CliAnalytics": "Cli Analytics", + "Search": "Ricerca", + "ClearFilter": "Filtro pulito", + "LicensePrivateKey": "Chiave privata della licenza", + "LicensePublicKey": "Licenza chiave pubblica", + "ApiKey": "Chiave API NuGet", + "ShowInvoiceRequestsOfOrganization": "Richieste di fattura", + "ShowQuestionsOfOrganization": "Domande", + "Question": "Domanda", + "Open": "Aperto", + "Questions": "Domande", + "InvoiceRequests": "Richieste di fattura", + "Address": "Indirizzo", + "TaxNo": "No fiscale", + "Permission:InvoiceRequest": "Richiesta di fattura", + "Permission:Question": "Domanda", + "AddNoteSuccessMessage": "Nota aggiunta con successo", + "NameSurname": "Nome cognome", + "Note": "Nota", + "Add": "Inserisci", + "ProjectDownloads": "Download del progetto", + "ShowProjectDownloadsOfOrganization": "Download del progetto", + "ShowAuditLogsOfOrganization": "Registri di controllo", + "Enum:EntityChangeType:0": "Creato", + "Enum:EntityChangeType:1": "Aggiornato", + "Enum:EntityChangeType:2": "Eliminato", + "TenantId": "ID inquilino", + "ChangeTime": "Cambia il tempo", + "EntityTypeFullName": "Nome completo del tipo di entità", + "AuditLogsFor{0}Organization": "Log di controllo per l'organizzazione \"{0}\"", + "Permission:EntityChange": "Modifica entità", + "Permission:ProjectDownload": "Download del progetto", + "Permission:PaymentRequest": "Richiesta di pagamento", + "CreatorEmailAddress": "Indirizzo email del creatore", + "EmailSendDate": "Data di invio dell'e-mail", + "PaymentRequestsFor{0}Organization": "Richieste di pagamento per l'organizzazione \"{0}\"", + "PaymentDetails": "Dettagli di pagamento", + "PaymentProduct": "Prodotto di pagamento", + "ProductName": "nome del prodotto", + "Code": "Codice", + "GenerateInvoice": "Genera fattura", + "ExportOrganizationsToExcel": "esportare in Excel", + "ThisExtensionIsNotAllowed": "Questa estensione non è consentita.", + "TheFileIsTooLarge": "Il file è troppo grande!", + "ArticleDeletionConfirmationMessage": "Sei sicuro di voler eliminare definitivamente questo articolo?", + "ChooseCoverImage": "Scegli un'immagine di copertina ..." + } +} \ No newline at end of file diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Base/Localization/Resources/FR.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Base/Localization/Resources/fr.json similarity index 97% rename from abp_io/AbpIoLocalization/AbpIoLocalization/Base/Localization/Resources/FR.json rename to abp_io/AbpIoLocalization/AbpIoLocalization/Base/Localization/Resources/fr.json index c9a6485426..c50d28f13a 100644 --- a/abp_io/AbpIoLocalization/AbpIoLocalization/Base/Localization/Resources/FR.json +++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Base/Localization/Resources/fr.json @@ -14,7 +14,7 @@ "Volo.AbpIo.Domain:020002": "Impossible de supprimer ce package NPM car les modules \"{Modules}\" utilisent ce package.", "Volo.AbpIo.Domain:020003": "Impossible de supprimer ce package NPM car les modules \"{Modules}\" utilisent ce package et les packages Nuget \"{NugetPackages}\" dépendent de ce package.", "Volo.AbpIo.Domain:020004": "Impossible de supprimer ce package Nuget car les modules \"{Modules}\" utilisent ce package.", - "WantToLearn?": "Vouloir apprendre?", + "WantToLearn?": "Vous voulez apprendre?", "ReadyToGetStarted?": "Prêt à commencer?", "JoinOurCommunity": "Rejoignez notre communauté", "GetStartedUpper": "COMMENCER", diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Base/Localization/Resources/hi.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Base/Localization/Resources/hi.json new file mode 100644 index 0000000000..cd1ec4491d --- /dev/null +++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Base/Localization/Resources/hi.json @@ -0,0 +1,37 @@ +{ + "culture": "hi", + "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": "अधिकतम मैक पता गणना पार हो गई है!", + "Volo.AbpIo.Domain:010011": "व्यक्तिगत लाइसेंस में 1 से अधिक डेवलपर नहीं हो सकते हैं!", + "Volo.AbpIo.Domain:010012": "लाइसेंस की अवधि समाप्त होने के एक महीने बाद तक लाइसेंस नहीं बढ़ाया जा सकता है!", + "Volo.AbpIo.Domain:020001": "इस NPM पैकेज को नहीं हटाया जा सका क्योंकि \"{NugetPackages}\" नुगेट पैकेज इस पैकेज पर निर्भर हैं।", + "Volo.AbpIo.Domain:020002": "यह NPM पैकेज नहीं हटा सका क्योंकि \"{मॉड्यूल}\" मॉड्यूल इस पैकेज का उपयोग कर रहे हैं।", + "Volo.AbpIo.Domain:020003": "इस NPM पैकेज को नहीं हटाया जा सका क्योंकि \"{मॉड्यूल}\" मॉड्यूल इस पैकेज का उपयोग कर रहे हैं और \"{NugetPackages}\" नुगेट पैकेज इस पैकेज पर निर्भर हैं।", + "Volo.AbpIo.Domain:020004": "इस Nuget पैकेज को हटाया नहीं जा सका क्योंकि \"{Modules}\" मॉड्यूल इस पैकेज का उपयोग कर रहे हैं।", + "WantToLearn?": "सीखना चाहते है?", + "ReadyToGetStarted?": "आरंभ करने के लिए तैयार हैं?", + "JoinOurCommunity": "हमारी संस्था से जुड़े", + "GetStartedUpper": "शुरू हो जाओ", + "ForkMeOnGitHub": "GitHub पर मेरे कांटा", + "Features": "विशेषताएं", + "GetStarted": "शुरू हो जाओ", + "Documents": "दस्तावेज़", + "Community": "समुदाय", + "ContributionGuide": "योगदान गाइड", + "Blog": "ब्लॉग", + "Commercial": "व्यावसायिक", + "MyAccount": "मेरा खाता", + "Permission:License": "लाइसेंस", + "Permission:UserInfo": "हमें जानकारी", + "SeeDocuments": "दस्तावेज़ देखें", + "Samples": "नमूने", + "Framework": "ढांचा", + "Support": "सहयोग" + } +} \ No newline at end of file diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Base/Localization/Resources/it.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Base/Localization/Resources/it.json new file mode 100644 index 0000000000..8a0e9d9e0b --- /dev/null +++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Base/Localization/Resources/it.json @@ -0,0 +1,37 @@ +{ + "culture": "it", + "texts": { + "Volo.AbpIo.Domain:010004": "Numero massimo di membri raggiunto!", + "Volo.AbpIo.Domain:010005": "Numero massimo di proprietari raggiunto!", + "Volo.AbpIo.Domain:010006": "Questo utente è già proprietario di questa organizzazione!", + "Volo.AbpIo.Domain:010007": "Questo utente è già uno sviluppatore in questa organizzazione!", + "Volo.AbpIo.Domain:010008": "Il numero di sviluppatori consentito non può essere inferiore al numero di sviluppatori corrente!", + "Volo.AbpIo.Domain:010009": "Il numero di sviluppatori consentito non può essere inferiore a 0!", + "Volo.AbpIo.Domain:010010": "Il numero massimo di indirizzi mac è stato superato!", + "Volo.AbpIo.Domain:010011": "La licenza personale non può avere più di 1 sviluppatore!", + "Volo.AbpIo.Domain:010012": "La licenza non può essere estesa un mese dopo la scadenza della licenza!", + "Volo.AbpIo.Domain:020001": "Impossibile eliminare questo pacchetto NPM perché i pacchetti Nuget \"{NugetPackages}\" dipendono da questo pacchetto.", + "Volo.AbpIo.Domain:020002": "Impossibile eliminare questo pacchetto NPM perché i moduli \"{Modules}\" utilizzano questo pacchetto.", + "Volo.AbpIo.Domain:020003": "Impossibile eliminare questo pacchetto NPM perché i moduli \"{Modules}\" utilizzano questo pacchetto e i pacchetti Nuget \"{NugetPackages}\" dipendono da questo pacchetto.", + "Volo.AbpIo.Domain:020004": "Impossibile eliminare questo pacchetto Nuget perché i moduli \"{Modules}\" utilizzano questo pacchetto.", + "WantToLearn?": "Vuoi imparare?", + "ReadyToGetStarted?": "Pronto per iniziare?", + "JoinOurCommunity": "Unisciti alla nostra community", + "GetStartedUpper": "INIZIARE", + "ForkMeOnGitHub": "Fork me su GitHub", + "Features": "Caratteristiche", + "GetStarted": "Iniziare", + "Documents": "Documenti", + "Community": "Comunità", + "ContributionGuide": "Guida al contributo", + "Blog": "Blog", + "Commercial": "Commerciale", + "MyAccount": "Il mio conto", + "Permission:License": "Licenza", + "Permission:UserInfo": "Informazioni utente", + "SeeDocuments": "Vedi Documenti", + "Samples": "Campioni", + "Framework": "Struttura", + "Support": "Supporto" + } +} \ No newline at end of file diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/en-GB.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/en-GB.json index 56f4ed934f..40b9fd3aa9 100644 --- a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/en-GB.json +++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/en-GB.json @@ -34,6 +34,34 @@ "JoinOurMarketingNewsletter": "Join our marketing newsletter", "WouldLikeToReceiveMarketingMaterials": "I would like to receive marketing materials e.g. product deals & special offers.", "StartUsingYourLicenseNow": "Start using your license now!", - "WelcomePage": "Welcome Page" + "WelcomePage": "Welcome Page", + "CompanyName": "Company name", + "YourCompanyName": "Your company name", + "FirstName": "First name", + "LastName": "Last name", + "Optional": "Optional", + "YourFirstName": "Your first name", + "YourLastName": "Your last name", + "SpecialOffer": "Special Offer", + "SpecialOfferMessage": "Hurry up! Prices are valid for a limited time.", + "DiscountRequest": "Discount Request", + "DiscountRequestDescribeCustomerQuestion": "Which of the following describes you?", + "DiscountRequestStudentEmailMessage": "Email Address must contain 'edu'.", + "DiscountRequestDeveloperCount": "How many developers are you?", + "DiscountRequestDeveloperCountExceedMessage": "We don't provide discounted license for companies that has over {0} developers.", + "DiscountRequestOrganizationName": "Company/organization/school name", + "Website": "Website", + "GithubUsername": "GitHub username", + "PhoneNumber": "Phone number", + "Country": "Country", + "DescribeABPCommercialUsage": "Describe the project you are planning to develop based on APB Commercial", + "DiscountRequestCertifyInformationMessage": "I certify all information is true and correct.", + "DiscountRequestReceived": "We have received your discount request.", + "DiscountRequestStatusMessage": "We will respond to you after checking the information you have provided.", + "MVCOrRazorPages": "MVC (Razor Pages)", + "Angular": "Angular", + "Blazor": "Blazor", + "New": "New", + "MongoDB": "MongoDB" } } \ No newline at end of file diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/en.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/en.json index 3c2a7cc59c..8259fb8160 100644 --- a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/en.json +++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/en.json @@ -291,6 +291,34 @@ "PayViaAmexCard": "How can I pay via my AMEX card?", "PayViaAmexCardDescription": "The default payment gateway 'Iyzico' may decline some AMEX credit cards due to the security measures. In this case, you can pay through the alternative payment gateway '2Checkout'.", "ThankYou": "Thank you", - "InvalidReCaptchaErrorMessage": "There was an error verifying reCAPTCHA. Please try again." + "InvalidReCaptchaErrorMessage": "There was an error verifying reCAPTCHA. Please try again.", + "CompanyName": "Company name", + "YourCompanyName": "Your company name", + "FirstName": "First name", + "LastName": "Last name", + "Optional": "Optional", + "YourFirstName": "Your first name", + "YourLastName": "Your last name", + "SpecialOffer": "Special Offer", + "SpecialOfferMessage": "Hurry up! Prices are valid for a limited time.", + "DiscountRequest": "Discount Request", + "DiscountRequestDescribeCustomerQuestion": "Which of the following describes you?", + "DiscountRequestStudentEmailMessage": "Email Address must contain 'edu'.", + "DiscountRequestDeveloperCount": "How many developers are you?", + "DiscountRequestDeveloperCountExceedMessage": "We don't provide discounted license for companies that has over {0} developers.", + "DiscountRequestOrganizationName": "Company/organization/school name", + "Website": "Website", + "GithubUsername": "GitHub username", + "PhoneNumber": "Phone number", + "Country": "Country", + "DescribeABPCommercialUsage": "Describe the project you are planning to develop based on APB Commercial", + "DiscountRequestCertifyInformationMessage": "I certify all information is true and correct.", + "DiscountRequestReceived": "We have received your discount request.", + "DiscountRequestStatusMessage": "We will respond to you after checking the information you have provided.", + "MVCOrRazorPages": "MVC (Razor Pages)", + "Angular": "Angular", + "Blazor": "Blazor", + "New": "New", + "MongoDB": "MongoDB" } } diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/FR.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/fr.json similarity index 96% rename from abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/FR.json rename to abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/fr.json index b2cbfa7651..c5f9f1db6c 100644 --- a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/FR.json +++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/fr.json @@ -8,16 +8,16 @@ "DeveloperCount": "Développeurs alloués / totaux", "QuestionCount": "Questions restantes / totales", "Unlimited": "Illimité", - "Owners": "Les propriétaires", + "Owners": "Propriétaires", "AddMember": "Ajouter un membre", "AddOwner": "Ajouter un propriétaire", "AddDeveloper": "Ajouter un développeur", "UserName": "Nom d'utilisateur", "Name": "Nom", "EmailAddress": "Adresse e-mail", - "Developers": "Les développeurs", + "Developers": "Développeurs", "LicenseType": "Type de licence", - "Manage": "Faire en sorte", + "Manage": "Gérer", "StartDate": "Date de début", "EndDate": "Date de fin", "Modules": "Modules", @@ -42,7 +42,7 @@ "NotOrganizationMember": "Vous n'êtes membre d'aucune organisation.", "UnsubscribeLicenseExpirationEmailSuccessTitle": "Désabonnement réussi", "UnsubscribeLicenseExpirationEmailSuccessMessage": "Vous ne recevrez plus d'e-mails de rappel de la date d'expiration de la licence.", - "IndexPageHeroSection": " Une plate-forme de développement Web complète intégrée cadre ", + "IndexPageHeroSection": "Une plate-forme de développement Web complète intégrée cadre ", "AbpCommercialShortDescription": "ABP Commercial fournit des modules d'application prédéfinis, des outils de développement rapide d'applications, des thèmes d'interface utilisateur professionnels, un support premium et plus encore.", "LiveDemo": "Démo en direct", "GetLicence": "Obtenez une licence", @@ -52,7 +52,7 @@ "Templates": "Modèles", "Developer": "Développeur", "Tools": "Outils", - "Premium": "Prime", + "Premium": "Premium", "PremiumSupport": "Assistance Premium", "PremiumForumSupport": "Assistance du forum Premium", "UI": "UI", @@ -61,26 +61,26 @@ "Send": "Envoyer", "Learn": "Apprendre", "AdditionalServices": "Des services supplémentaires", - "WhatIsABPFramework": "QUEL EST LE CADRE ABP?", + "WhatIsABPFramework": "QU'EST-CE QUE LE FRAMEWORK ABP?", "OpenSourceBaseFramework": "Framework de base Open Source", "ABPFrameworkExplanation": "

ABP Commercial est basé sur ABP Framework, un framework d'applications Web open source et communautaire pour ASP.NET Core.

ABP Framework fournit une excellente infrastructure pour écrire maintenable et extensible et du code testable avec les meilleures pratiques.

Construit et intégré à des outils populaires que vous connaissez déjà. Faible courbe d'apprentissage, adaptation facile, développement confortable.

", "Modular": "Modulaire", "MicroserviceCompatible": "Compatible avec les microservices", "DomainDrivenDesignInfrastructure": "Infrastructure de conception pilotée par domaine", - "MultiTenancy": "Locations multiples", + "MultiTenancy": "Multi-souscrivant", "DistributedMessaging": "Messagerie distribuée", "DynamicProxying": "Proxying dynamique", - "BackgroundJobs": "Emplois d'arrière-plan", + "BackgroundJobs": "Tâches d'arrière-plan", "AuditLogging": "Journalisation d'audit", "BLOBStoring": "Stockage BLOB", - "BundlingMinification": "Regroupement et minification", + "BundlingMinification": "Bundling et minification", "AdvancedLocalization": "Localisation avancée", "ManyMore": "Beaucoup plus", - "ExploreTheABPFramework": "Explorez le cadre ABP", - "WhyUseTheABPCommercial": "Pourquoi utiliser la publicité ABP?", + "ExploreTheABPFramework": "Explorez le Framework ABP", + "WhyUseTheABPCommercial": "Pourquoi utiliser ABP Commercial?", "WhyUseTheABPCommercialExplanation": "

La création d'applications Web de niveau entreprise peut être complexe et prendre du temps.

ABP Commercial offre l'infrastructure de base parfaite nécessaire pour tous les ASP.NET Core modernes de niveau entreprise solutions basées. De la conception au déploiement, l'ensemble du cycle de développement est optimisé par les fonctionnalités et modules intégrés d'ABP.

", "StartupTemplatesShortDescription": "Les modèles de démarrage vous permettent de démarrer votre projet en quelques secondes.", - "UIFrameworksOptions": "Options de cadres d'interface utilisateur;", + "UIFrameworksOptions": "Options de frameworks d'interface utilisateur;", "DatabaseProviderOptions": "Options du fournisseur de base de données;", "PreBuiltApplicationModules": "Modules d'application prédéfinis", "PreBuiltApplicationModulesShortDescription": "Les exigences d'application les plus courantes sont déjà développées pour vous en tant que modules réutilisables.", @@ -92,19 +92,19 @@ "LanguageManagement": "Gestion de la langue", "TextTemplateManagement": "Gestion des modèles de texte", "See All Modules": "VoirTousModules", - "ABPSuite": "Suite ABP", + "ABPSuite": "ABP Suite", "AbpSuiteShortDescription": "ABP Suite est un outil complémentaire à ABP Commercial.", "AbpSuiteExplanation": "Il vous permet de créer des pages Web en quelques minutes. C'est un outil global .NET Core qui peut être installé à partir de la ligne de commande. Il peut créer une nouvelle solution ABP, générer des pages CRUD de la base de données vers le front-end.", - "Details": "Des détails", + "Details": "Détails", "LeptonTheme": "Thème Lepton", "ProfessionalModernUIThemes": "Thèmes d'interface utilisateur professionnels et modernes", "LeptonThemeExplanation": "Lepton fournit une gamme de thèmes d'administration Bootstrap qui servent de base solide pour tout projet nécessitant un tableau de bord d'administration.", "DefaultTheme": "Thème par défaut", - "MaterialTheme": "Thème matériel", + "MaterialTheme": "Thème Material", "Default2Theme": "Thème par défaut 2", "DarkTheme": "Thème sombre", "DarkBlueTheme": "Thème bleu foncé", - "LightTheme": "Thème léger", + "LightTheme": "Thème clair", "ProudToWorkWith": "Fier de travailler avec", "OurConsumers": "Des centaines d'entreprises et de développeurs dans plus de 50 pays dans le monde font confiance à ABP Commercial.", "JoinOurConsumers": "Rejoignez-les et créez rapidement des produits incroyables.", @@ -125,14 +125,14 @@ "Contact": "Contacter", "TellUsWhatYouNeed": "Dites-nous ce dont vous avez besoin.", "YourMessage": "Votre message", - "YourFullName": "Ton nom complet", + "YourFullName": "Votre nom complet", "EmailField": "Adresse e-mail", "YourEmailAddress": "Votre adresse email", "HowMayWeHelpYou": "Comment pouvons nous vous aider?", "SendMessage": "Envoyer le message", "Success": "Succès", "WeWillReplyYou": "Nous avons reçu votre message et vous contacterons sous peu.", - "GoHome": "Rentrer chez soi", + "GoHome": "Retour à l'acceuil", "CreateLiveDemo": "Créer une démo en direct", "RegisterToTheNewsletter": "Inscrivez-vous à la newsletter pour recevoir des informations concernant ABP.IO, y compris les nouvelles versions, etc.", "EnterYourEmailOrLogin": "Saisissez votre adresse e-mail pour créer votre démo ou Connectez-vous à l'aide de votre compte existant.", @@ -264,7 +264,7 @@ "Documentation": "Documentation", "SeeModulesDocument": "Voir le document des modules pour une liste de tous les modules commerciaux (pro) et leurs documents.", "Pricing": "Tarification", - "PricingExplanation": "Choisissez les fonctionnalités et fonctionnalités dont votre entreprise a besoin aujourd'hui. Mettez à niveau facilement au fur et à mesure que votre entreprise se développe.", + "PricingExplanation": "Choisissez les fonctionnalités dont votre entreprise a besoin aujourd'hui. Mettez à niveau facilement au fur et à mesure que votre entreprise se développe.", "Team": "Équipe", "Business": "Affaires", "Enterprise": "Entreprise", diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/hi.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/hi.json new file mode 100644 index 0000000000..54216f7719 --- /dev/null +++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/hi.json @@ -0,0 +1,296 @@ +{ + "culture": "hi", + "texts": { + "OrganizationManagement": "संगठन का प्रबंधन", + "OrganizationList": "संगठन सूची", + "Volo.AbpIo.Commercial:010003": "आप इस संगठन के मालिक नहीं हैं!", + "OrganizationNotFoundMessage": "कोई संगठन नहीं मिला!", + "DeveloperCount": "आवंटित / कुल डेवलपर्स", + "QuestionCount": "शेष / कुल प्रश्न", + "Unlimited": "असीमित", + "Owners": "मालिकों", + "AddMember": "सदस्य जोड़ें", + "AddOwner": "मालिक जोड़ें", + "AddDeveloper": "डेवलपर जोड़ें", + "UserName": "उपयोगकर्ता नाम", + "Name": "नाम", + "EmailAddress": "ईमेल पता", + "Developers": "डेवलपर्स", + "LicenseType": "लाइसेंस के प्रकार", + "Manage": "प्रबंधित", + "StartDate": "आरंभ करने की तिथि", + "EndDate": "समाप्ति तिथि", + "Modules": "मॉड्यूल", + "LicenseExtendMessage": "आपकी लाइसेंस समाप्ति तिथि {0} तक बढ़ा दी गई है", + "LicenseUpgradeMessage": "आपका लाइसेंस {0} में अपग्रेड किया गया है", + "LicenseAddDeveloperMessage": "{0} डेवलपर्स ने आपके लाइसेंस में जोड़ा", + "Volo.AbpIo.Commercial:010004": "निर्दिष्ट उपयोगकर्ता नहीं मिल सकता है! उपयोगकर्ता को पहले से ही पंजीकृत होना चाहिए।", + "MyOrganizations": "मेरे संगठन", + "ApiKey": "एपीआई कुंजी", + "UserNameNotFound": "उपयोगकर्ता नाम {0} का कोई उपयोगकर्ता नहीं है", + "SuccessfullyAddedToNewsletter": "हमारे न्यूज़लेटर की सदस्यता के लिए धन्यवाद!", + "MyProfile": "मेरी प्रोफाइल", + "EmailNotValid": "कृपया एक वैध ई - मेल एड्रेस डालें।", + "JoinOurMarketingNewsletter": "हमारे विपणन समाचार पत्र में शामिल हों", + "WouldLikeToReceiveMarketingMaterials": "मैं उत्पाद सौदों और विशेष प्रस्तावों जैसे विपणन सामग्री प्राप्त करना चाहता हूं।", + "StartUsingYourLicenseNow": "अब अपने लाइसेंस का उपयोग शुरू करें!", + "WelcomePage": "स्वागत पृष्ठ", + "UnsubscriptionExpireEmail": "लाइसेंस समाप्ति तिथि अनुस्मारक ईमेल से सदस्यता समाप्त करें", + "UnsubscribeLicenseExpireEmailReminderMessage": "इस ईमेल सदस्यता में केवल आपकी लाइसेंस समाप्ति तिथि याद दिलाने की होती है।", + "UnsubscribeFromLicenseExpireEmails": "यदि आप अपने लाइसेंस की समाप्ति तिथि के बारे में ईमेल प्राप्त नहीं करना चाहते हैं, तो आप किसी भी समय अपनी सदस्यता समाप्त कर सकते हैं।", + "Unsubscribe": "सदस्यता रद्द", + "NotOrganizationMember": "आप किसी संगठन के सदस्य नहीं हैं।", + "UnsubscribeLicenseExpirationEmailSuccessTitle": "सफलतापूर्वक सदस्यता समाप्त कर दी गई", + "UnsubscribeLicenseExpirationEmailSuccessMessage": "अब आपको लाइसेंस समाप्ति तिथि अनुस्मारक ईमेल प्राप्त नहीं होंगे।", + "IndexPageHeroSection": " एक पूर्ण वेब विकास मंच अंतर्निहित ढांचा ", + "AbpCommercialShortDescription": "एबीपी कमर्शियल प्री-बिल्ट एप्लिकेशन मॉड्यूल, रैपिड एप्लिकेशन डेवलपमेंट टूलिंग, पेशेवर यूआई थीम, प्रीमियम सपोर्ट आदि प्रदान करता है।", + "LiveDemo": "लाइव डेमो", + "GetLicence": "एक लाइसेंस प्राप्त करें", + "Application": "आवेदन", + "StartupTemplates": "स्टार्टअप टेम्पलेट", + "Startup": "चालू होना", + "Templates": "टेम्पलेट्स", + "Developer": "डेवलपर", + "Tools": "उपकरण", + "Premium": "प्रीमियम", + "PremiumSupport": "प्रीमियम सहायता", + "PremiumForumSupport": "प्रीमियम फोरम समर्थन", + "UI": "यूआई", + "Themes": "विषयों", + "JoinOurNewsletter": "हमारे समाचार पत्र शामिल हों", + "Send": "संदेश", + "Learn": "सीखना", + "AdditionalServices": "अतिरिक्त सेवाएं", + "WhatIsABPFramework": "ABP फ्रेमवर्क क्या है?", + "OpenSourceBaseFramework": "ओपन सोर्स बेस फ्रेमवर्क", + "ABPFrameworkExplanation": "

ABP कमर्शियल ASP.NET Core पर एक खुला स्रोत और समुदाय संचालित वेब एप्लीकेशन फ्रेमवर्क है। और सर्वोत्तम प्रथाओं के साथ परीक्षण योग्य कोड।

आप पहले से ही जानते हैं कि लोकप्रिय उपकरणों पर निर्मित और एकीकृत। कम सीखने की अवस्था, आसान अनुकूलन, आरामदायक विकास। ", + "Modular": "मॉड्यूलर", + "MicroserviceCompatible": "माइक्रोसिस्ट सेवा संगत", + "DomainDrivenDesignInfrastructure": "डोमेन संचालित डिज़ाइन इन्फ्रास्ट्रक्चर", + "MultiTenancy": "बहु किरायेदारी", + "DistributedMessaging": "वितरित संदेश", + "DynamicProxying": "गतिशील प्रॉक्सी", + "BackgroundJobs": "बैकग्राउंड जॉब्स", + "AuditLogging": "ऑडिट लॉगिंग", + "BLOBStoring": "ब्लॉब भंडारण", + "BundlingMinification": "बंडलिंग और न्यूनतमकरण", + "AdvancedLocalization": "उन्नत स्थानीयकरण", + "ManyMore": "बहुत सारी", + "ExploreTheABPFramework": "ABP फ्रेमवर्क का अन्वेषण करें", + "WhyUseTheABPCommercial": "एबीपी कमर्शियल का उपयोग क्यों करें?", + "WhyUseTheABPCommercialExplanation": "

बिल्डिंग एंटरप्राइज-ग्रेड वेब एप्लिकेशन जटिल और समय लेने वाली हो सकती हैं।

ABP कमर्शियल सभी आधुनिक एंटरप्राइज-ग्रेड ASP.NET Core के लिए आवश्यक सही आधारभूत संरचना प्रदान करता है। आधारित समाधान। डिज़ाइन से परिनियोजन तक, संपूर्ण विकास चक्र ABP की अंतर्निहित विशेषताओं और मॉड्यूल द्वारा सशक्त है। हम और हमारे साथी प्रदान कर सकते हैं; ", + "CustomProjectDevelopment": "कस्टम परियोजना विकास", + "CustomProjectDevelopmentExplanation": "अपने कस्टम प्रोजेक्ट्स के लिए समर्पित डेवलपर्स।", + "PortingExistingProjects": "मौजूदा परियोजनाओं को पोर्ट करना", + "PortingExistingProjectsExplanation": "एबीपी प्लेटफॉर्म पर अपनी विरासत परियोजनाओं को माइग्रेट करना।", + "LiveSupport": "लाइव सहायता", + "LiveSupportExplanation": "जरूरत पड़ने पर लाइव रिमोट सपोर्ट का विकल्प।", + "Training": "प्रशिक्षण", + "TrainingExplanation": "अपने डेवलपर्स के लिए समर्पित प्रशिक्षण।", + "OnBoarding": "ज्ञानप्राप्ति", + "OnBoardingExplanation": "अपने विकास, CI और सीडी वातावरण को सेटअप करने में मदद करें।", + "PrioritizedTechnicalSupport": "प्राथमिक तकनीकी सहायता", + "PremiumSupportExplanation": "एबीपी ढांचे के महान सामुदायिक समर्थन के अलावा, हमारी सहायता टीम उच्च प्राथमिकता वाले वाणिज्यिक उपयोगकर्ताओं की तकनीकी सवालों और समस्याओं का जवाब देती है।", + "SeeTheSupportOptions": "समर्थन विकल्प देखें", + "Contact": "संपर्क करें", + "TellUsWhatYouNeed": "अपनी ज़रूरत के बारे में हमें बताएं।", + "YourMessage": "आपका संदेश", + "YourFullName": "आपका पूरा नाम", + "EmailField": "ईमेल पता", + "YourEmailAddress": "आपका ईमेल पता", + "HowMayWeHelpYou": "हम कैसे आपकी सहायता कर सकते हैं?", + "SendMessage": "मेसेज भेजें", + "Success": "सफलता", + "WeWillReplyYou": "हमें आपका संदेश प्राप्त हुआ और शीघ्र ही संपर्क में आएगा।", + "GoHome": "घर जाओ", + "CreateLiveDemo": "लाइव डेमो बनाएँ", + "RegisterToTheNewsletter": "ABP.IO के बारे में जानकारी प्राप्त करने के लिए न्यूज़लेटर के लिए रजिस्टर करें, जिसमें नई रिलीज़ आदि शामिल हैं।", + "EnterYourEmailOrLogin": "अपने मौजूदा खाते का उपयोग करके अपना डेमो बनाने के लिए अपना ई-मेल पता दर्ज करें या अपना प्रदर्शन लॉगिन करें।", + "ApplicationTemplate": "एप्लिकेशन टेम्पलेट", + "ApplicationTemplateExplanation": "एप्लिकेशन स्टार्टअप टेम्पलेट का उपयोग एक नया वेब एप्लिकेशन बनाने के लिए किया जाता है।", + "EfCoreProvider": "इकाई ढाँचा (SQL सर्वर, MySQL, PostgreSQL, Oracle और अन्य का समर्थन करता है)", + "AlreadyIncludedInTemplateModules": "निम्नलिखित मॉड्यूल पहले से ही इस टेम्पलेट में शामिल और कॉन्फ़िगर किए गए हैं:", + "ApplicationTemplateArchitecture": "यह एप्लिकेशन टेम्पलेट tiered आर्किटेक्चर का भी समर्थन करता है जहां UI लेयर, API लेयर और ऑथेंटिकेशन सर्विस को शारीरिक रूप से अलग किया जाता है।", + "SeeTheGuideOrGoToTheLiveDemo": "इस टेम्पलेट के बारे में तकनीकी जानकारी के लिए डेवलपर गाइड देखें या लाइव डेमो पर जाएं।", + "DeveloperGuide": "डेवलपर गाइड", + "ModuleTemplate": "मॉड्यूल टेम्पलेट", + "ModuleTemplateExplanation1": "आप एक मॉड्यूल बनाना और विभिन्न अनुप्रयोगों में पुन: उपयोग करना चाहते हैं? यह स्टार्टअप टेम्पलेट एक पुन: प्रयोज्य अनुप्रयोग मॉड्यूल या microservice बनाने के लिए शुरू करने के लिए सब कुछ तैयार करता है।", + "ModuleTemplateExplanation2": "

आप एकल मॉड्यूल के लिए एकल या एकाधिक UI फ्रेमवर्क, एकल या एकाधिक डेटाबेस प्रदाता का समर्थन कर सकते हैं। स्टार्टअप टेम्प्लेट को चलाने के लिए कॉन्फ़िगर किया गया है और अपने मॉड्यूल का परीक्षण करें यूनिट और एकीकरण परीक्षण के बुनियादी ढांचे के अलावा न्यूनतम आवेदन में।

इस टेम्पलेट के बारे में तकनीकी जानकारी के लिए डेवलपर गाइड देखें। ", + "WithAllStyleOptions": "सभी शैली विकल्पों के साथ", + "Demo": "डेमो", + "SeeAllModules": "सभी मॉड्यूल देखें", + "ABPCLIExplanation": "ABP CLI (कमांड लाइन इंटरफेस) ABP आधारित समाधानों के लिए कुछ सामान्य ऑपरेशन करने के लिए एक कमांड लाइन टूल है।", + "ABPSuiteEasilyCURD": "एबीपी सूट एक उपकरण है जो आपको आसानी से CRUD पेज बनाने की अनुमति देता है", + "WeAreHereToHelp": "हम यहाँ हैं मदद ", + "BrowseOrAskQuestion": "आप हमारे सहायता विषयों को ब्राउज़ कर सकते हैं या अक्सर पूछे जाने वाले प्रश्नों में खोज कर सकते हैं, या आप संपर्क फ़ॉर्म का उपयोग करके हमसे एक प्रश्न पूछ सकते हैं।", + "SearchQuestionPlaceholder": "अक्सर पूछे जाने वाले प्रश्नों में खोजें", + "WhatIsTheABPCommercial": "ABP कमर्शियल क्या है?", + "WhatAreDifferencesThanAbpFramework": "ओपन सोर्स ABP फ्रेमवर्क और ABP कमर्शियल के बीच क्या अंतर हैं?", + "ABPCommercialExplanation": "एबीपी कमर्शियल, खुले स्रोत के शीर्ष पर बनाए गए प्रीमियम मॉड्यूल, टूल, थीम और सेवाओं का एक सेट है जो ABP फ्रेमवर्क है। एबीपी कमर्शियल को एबीपी फ्रेमवर्क के पीछे उसी टीम द्वारा विकसित और समर्थित किया जा रहा है।", + "WhatAreDifferencesThanABPFrameworkExplanation": "

ABP फ्रेमवर्क ASP.NET Core के लिए एक मॉड्यूलर, थीमेबल, माइक्रो-सर्विस संगत एप्लिकेशन डेवलपमेंट फ्रेमवर्क है। यह आपको हर नई परियोजना के लिए खुद को दोहराने के बजाय अपने खुद के व्यवसाय कोड पर ध्यान केंद्रित करने के लिए एक पूर्ण वास्तुकला और एक मजबूत बुनियादी ढांचा प्रदान करता है। यह सॉफ्टवेयर विकास सर्वोत्तम प्रथाओं और लोकप्रिय उपकरणों पर आधारित है जिन्हें आप पहले से जानते हैं।

एबीपी फ्रेमवर्क पूरी तरह से मुक्त, खुला स्रोत और समुदाय-संचालित है। यह एक मुफ्त थीम और कुछ पूर्व-निर्मित मॉड्यूल (जैसे पहचान प्रबंधन और किरायेदार प्रबंधन) प्रदान करता है। ", + "VisitTheFrameworkVSCommercialDocument": "अधिक जानकारी के लिए, निम्न लिंक पर जाएं {1} ", + "ABPCommercialFollowingBenefits": "एबीपी वाणिज्यिक एबीपी ढांचे के शीर्ष पर निम्नलिखित लाभ जोड़ता है;", + "Professional": "पेशेवर", + "UIThemes": "यूआई थीम", + "EnterpriseModules": "एंटरप्राइज रेडी, फीचर से भरपूर, पहले से निर्मित एप्लिकेशन मॉड्यूल (जैसे पहचान सर्वर प्रबंधन, सास प्रबंधन, भाषा प्रबंधन)", + "ToolingToSupport": "अपनी विकास उत्पादकता का समर्थन करने का टूल", + "PremiumSupportLink": "प्रीमियम समर्थन ", + "WhatDoIDownloadABPCommercial": "जब मैं एबीपी कमर्शियल खरीदता हूं तो क्या डाउनलोड करता हूं?", + "CreateUnlimitedSolutions": "एक बार जब आप एक एबीपी कमर्शियल लाइसेंस खरीदते हैं, तो आप असीमित समाधान बना पाएंगे, जैसे कि Get Started दस्तावेज़ में वर्णित है।", + "ABPCommercialSolutionExplanation": "जब आप एक नया एप्लिकेशन बनाते हैं, तो आपको अपनी प्राथमिकताओं के आधार पर एक विज़ुअल स्टूडियो समाधान (एक स्टार्टअप टेम्प्लेट) मिलता है। डाउनलोड किए गए समाधान में आपके लिए पहले से इंस्टॉल और कॉन्फ़िगर किए गए वाणिज्यिक मॉड्यूल और थीम हैं। यदि आप चाहें तो आप पहले से स्थापित मॉड्यूल को हटा सकते हैं या किसी अन्य मॉड्यूल को जोड़ सकते हैं। सभी मॉड्यूल और थीम डिफ़ॉल्ट रूप से एक NuGet / NPM पैकेज का उपयोग किया जाता है।", + "StartDevelopWithTutorials": "डाउनलोड किया गया समाधान अच्छी तरह से वास्तुकला और दस्तावेज है। आप अपने स्वयं के व्यवसाय कोड को इस आधार पर विकसित करना शुरू कर सकते हैं कि वह ट्यूटोरियल्स का अनुसरण कर सकता है", + "TryTheCommercialDemo": "ABP कमर्शियल स्टार्टअप टेम्प्लेट का उपयोग करके बनाए गए एक नमूना अनुप्रयोग को देखने के लिए आप डेमो का प्रयास कर सकते हैं।", + "HowManyProducts": "ABP वाणिज्यिक का उपयोग करके मैं कितने विभिन्न उत्पाद / समाधान बना सकता हूं?", + "HowManyProductsExplanation": "ABP प्रोजेक्ट बनाने की कोई सीमा नहीं है। आप जितने चाहें उतने प्रोजेक्ट बना सकते हैं, उन्हें विकसित कर सकते हैं और उन्हें विभिन्न सर्वरों पर अपलोड कर सकते हैं।", + "HowManyDevelopers": "एबीपी कमर्शियल पर कितने डेवलपर काम कर सकते हैं?", + "HowManyDevelopersExplanation": "एबीपी वाणिज्यिक लाइसेंस प्रति डेवलपर हैं। विभिन्न लाइसेंस प्रकारों में अलग-अलग डेवलपर सीमाएँ होती हैं। हालाँकि, जब भी आपको आवश्यकता हो, आप किसी भी प्रकार के लाइसेंस में अधिक डेवलपर्स जोड़ सकते हैं। लाइसेंस प्रकार, डेवलपर सीमा और अतिरिक्त डेवलपर लागतों के लिए कीमतें पृष्ठ देखें।", + "ChangingLicenseType": "क्या मैं भविष्य में अपना लाइसेंस प्रकार बदल सकता हूं?", + "ChangingLicenseTypeExplanation": "आप अपने समान लाइसेंस प्रकार में हमेशा नए डेवलपर्स को जोड़ सकते हैं। यह भी देखें \"एबीपी कमर्शियल पर कितने डेवलपर काम कर सकते हैं?\"। आप गणना मूल्य अंतर का भुगतान करके एक उच्च लाइसेंस के लिए भी अपग्रेड कर सकते हैं। जब आप उच्च लाइसेंस योजना में अपग्रेड करते हैं, तो आपको नई योजना का लाभ मिलता है, लेकिन लाइसेंस अपग्रेड लाइसेंस की समाप्ति की तारीख को नहीं बदलता है।", + "LicenseExtendUpgradeDiff": "लाइसेंस विस्तार और उन्नयन के बीच क्या अंतर है?", + "LicenseExtendUpgradeDiffExplanation": " विस्तार: अपने लाइसेंस का विस्तार / नवीनीकरण करके, आप प्रीमियम समर्थन प्राप्त करना और मॉड्यूल और थीम के लिए प्रमुख अपडेट प्राप्त करना जारी रखेंगे। इसके अलावा, आप नई परियोजनाओं को जारी रखने में सक्षम होंगे। और आप अभी भी एबीपी सूट का उपयोग कर पाएंगे जो आपके विकास को गति देता है।


उन्नयन: अपने लाइसेंस को अपग्रेड करके, आप एक उच्च लाइसेंस योजना को बढ़ावा देंगे जिससे आप अतिरिक्त लाभ प्राप्त कर सकेंगे। । लाइसेंस योजनाओं के बीच अंतर की जांच करने के लिए लाइसेंस तुलना तालिका देखें। दूसरी ओर, जब आप अपग्रेड करते हैं, तो आपकी लाइसेंस की समाप्ति तिथि नहीं बदलेगी! > अपनी लाइसेंस की अंतिम तिथि बढ़ाने के लिए, आपको अपने लाइसेंस का विस्तार करना होगा।", + "LicenseRenewalCost": "1 वर्ष के बाद लाइसेंस नवीनीकरण लागत क्या है?", + "LicenseRenewalCostExplanation": "सभी एबीपी वाणिज्यिक स्थायी लाइसेंसों का नवीकरण (विस्तार) दर लाइसेंस सूची मूल्य का {0} है। मानक टीम लाइसेंस का नवीनीकरण मूल्य $ {1} है, मानक व्यवसाय लाइसेंस $ {2} है और मानक एंटरप्राइज़ लाइसेंस $ {3} है। यदि आप पहले से ही ग्राहक हैं, तो उपलब्ध नवीनीकरण मूल्य निर्धारण की समीक्षा करने के लिए अपने खाते में लॉग इन करें ।", + "HowDoIRenewMyLicense": "मैं अपने लाइसेंस का नवीनीकरण कैसे करूँ?", + "HowDoIRenewMyLicenseExplanation": "आप अपने लाइसेंस को संगठन प्रबंधन पृष्ठ पर नेविगेट करके नवीनीकृत कर सकते हैं। हमारी रियायती अर्ली रिन्यूअल दरों का लाभ उठाने के लिए, सुनिश्चित करें कि आप अपने लाइसेंस की समय सीमा समाप्त होने से पहले नवीनीकरण करें। हालाँकि, जब आपका प्रारंभिक नवीनीकरण अवसर बंद हो जाता है, तो यह जानने की चिंता न करें। आपकी सदस्यता समाप्त होने से पहले आपको 2 अनुस्मारक ई-मेल प्राप्त होंगे। हम उन्हें 30 दिन, समाप्ति से 7 दिन पहले भेज देंगे।", + "IsSourceCodeIncluded": "क्या मेरे लाइसेंस में वाणिज्यिक मॉड्यूल और थीम का स्रोत कोड शामिल है?", + "IsSourceCodeIncludedExplanation1": "आपके द्वारा खरीदे गए लाइसेंस प्रकार पर निर्भर करता है:", + "IsSourceCodeIncludedExplanation2": " टीम : आपका समाधान मॉड्यूल और थीम को NuGet और NPM पैकेज के रूप में उपयोग करता है। इसमें उनका स्रोत कोड शामिल नहीं है। इस तरह, जब भी कोई नया संस्करण उपलब्ध हो, आप इन मॉड्यूल और थीम को आसानी से अपग्रेड कर सकते हैं। हालाँकि, आप मॉड्यूल और थीम के स्रोत कोड प्राप्त नहीं कर सकते।", + "IsSourceCodeIncludedExplanation3": " व्यवसाय / उद्यम : टीम लाइसेंस के अतिरिक्त, आप किसी भी मॉड्यूल या थीम की आवश्यकता के स्रोत कोड को डाउनलोड करने में सक्षम हैं। तुम भी एक विशेष मॉड्यूल के लिए NuGet / NPM पैकेज संदर्भ निकाल सकते हैं और इसे पूरी तरह से बदलने के लिए अपने समाधान के लिए अपने स्रोत कोड को सीधे जोड़ सकते हैं।", + "IsSourceCodeIncludedExplanation4": "

एक मॉड्यूल के स्रोत कोड को आपके समाधान में शामिल करना आपको उस मॉड्यूल को अनुकूलित करने की अधिकतम स्वतंत्रता देता है। हालाँकि, तब नया संस्करण जारी होने पर मॉड्यूल को स्वचालित रूप से अपग्रेड करना संभव नहीं होगा।

किसी भी लाइसेंस में ABP सुइट स्रोत कोड शामिल नहीं है, जो एक बाहरी उपकरण है जो आपके लिए कोड बनाता है और सहायता करता है आपके विकास के लिए।

लाइसेंस प्रकारों के अन्य अंतरों के लिए मूल्य निर्धारण पृष्ठ देखें। ", + "ChangingDevelopers": "क्या मैं भविष्य में अपने संगठन के पंजीकृत डेवलपर्स को बदल सकता हूं?", + "ChangingDevelopersExplanation": "अपने लाइसेंस में नए डेवलपर्स को जोड़ने के अलावा, आप मौजूदा डेवलपर्स को भी बदल सकते हैं (आप एक डेवलपर को हटा सकते हैं और एक ही सीट पर एक नया जोड़ सकते हैं) बिना किसी अतिरिक्त लागत के।", + "WhatHappensWhenLicenseEnds": "मेरे लाइसेंस की अवधि समाप्त होने पर क्या होता है?", + "WhatHappensWhenLicenseEndsExplanation1": "ABP कमर्शियल लाइसेंस का प्रकार स्थायी लाइसेंस है। आपके लाइसेंस की समय सीमा समाप्त होने के बाद, आप अपना प्रोजेक्ट विकसित करना जारी रख सकते हैं। और आप अपने लाइसेंस को नवीनीकृत करने के लिए बाध्य नहीं हैं। आपका लाइसेंस एक वर्ष के अपडेट और समर्थन योजना के साथ आता है। नई सुविधाओं को प्राप्त करने के लिए, प्रदर्शन में वृद्धि, बग फिक्स, समर्थन और एबीपी सूट का उपयोग करना जारी रखें, प्रत्येक वर्ष अपनी योजना को नवीनीकृत करना सुनिश्चित करें। जब आपका लाइसेंस समाप्त हो जाता है, तो आप निम्नलिखित लाभ प्राप्त नहीं कर पाएंगे;", + "WhatHappensWhenLicenseEndsExplanation2": "आप एबीपी कमर्शियल का उपयोग करके नए समाधान नहीं बना सकते हैं, लेकिन आप अपने मौजूदा अनुप्रयोगों को हमेशा के लिए विकसित कर सकते हैं।", + "WhatHappensWhenLicenseEndsExplanation3": "आप अपने मुख्य संस्करण के भीतर मॉड्यूल और विषयों के लिए अद्यतन प्राप्त करने में सक्षम होंगे। उदाहरण के लिए; यदि आप किसी मॉड्यूल के v3.2.0 का उपयोग कर रहे हैं, तो आप उस मॉड्यूल के v3.x.x (v3.3.0, v3.5.2 ... आदि) के लिए अपडेट प्राप्त कर सकते हैं। लेकिन आपको अगले प्रमुख संस्करण के लिए अपडेट नहीं मिल सकता है (जैसे v4.x, v5.x)", + "WhatHappensWhenLicenseEndsExplanation4": "आप अपने लाइसेंस समाप्त होने के बाद एबीपी वाणिज्यिक मंच में जोड़े गए नए मॉड्यूल और थीम स्थापित नहीं कर सकते।", + "WhatHappensWhenLicenseEndsExplanation5": "आप एबीपी सूट का उपयोग नहीं कर सकते।", + "WhatHappensWhenLicenseEndsExplanation6": "आपको अब और प्रीमियम सहायता नहीं मिल सकती है।", + "WhatHappensWhenLicenseEndsExplanation7": "यदि आप इन लाभों को प्राप्त करना जारी रखना चाहते हैं तो आप अपनी सदस्यता को नवीनीकृत कर सकते हैं। जब आप अपनी सदस्यता को नवीनीकृत करते हैं तो 20% छूट मिलती है।", + "WhenShouldIRenewMyLicense": "मुझे अपना लाइसेंस कब नवीनीकृत करना चाहिए?", + "WhenShouldIRenewMyLicenseExplanation1": "यदि आप अपना लाइसेंस समाप्त होने के बाद अपने लाइसेंस का नवीनीकरण 1 महीने के भीतर करते हैं, तो कुल लाइसेंस मूल्य पर% 20 छूट लागू होगी।", + "WhenShouldIRenewMyLicenseExplanation2": "यदि आप अपनी लाइसेंस की समाप्ति तिथि से 1 महीने के बाद अपना लाइसेंस नवीनीकृत करते हैं, तो नवीनीकरण मूल्य लाइसेंस खरीद मूल्य के समान होगा और आपके नवीकरण के लिए कोई छूट नहीं होगी।", + "TrialPlan": "क्या आपके पास एक परीक्षण योजना है?", + "TrialPlanExplanation": "अभी के लिए, एबीपी कमर्शियल में ट्रायल प्लान नहीं है। टीम लाइसेंस के लिए हम 30 दिन की मनी बैक गारंटी प्रदान करते हैं। आप पहले 30 दिनों में धनवापसी का अनुरोध कर सकते हैं। बिजनेस और एंटरप्राइज लाइसेंस के लिए, हम 30 दिनों में 60% रिफंड प्रदान करते हैं। ऐसा इसलिए है क्योंकि व्यवसाय और एंटरप्राइज़ लाइसेंस में सभी मॉड्यूल और थीम का पूर्ण स्रोत कोड शामिल है।", + "DoYouAcceptBankWireTransfer": "क्या आप बैंक वायर ट्रांसफर स्वीकार करते हैं?", + "DoYouAcceptBankWireTransferExplanation": "हां, हम बैंक वायर ट्रांसफर स्वीकार करते हैं।
बैंक वायर ट्रांसफर के माध्यम से लाइसेंस राशि भेजने के बाद, हमें अपनी रसीद और अनुरोधित लाइसेंस प्रकार ई-मेल के माध्यम से भेजें।
हमारे अंतरराष्ट्रीय बैंक खाते की जानकारी:", + "HowToUpgrade": "नया संस्करण उपलब्ध होने पर मौजूदा एप्लिकेशन को कैसे अपग्रेड किया जाए?", + "HowToUpgradeExplanation1": "जब आप ABP कमर्शियल का उपयोग करके एक नया एप्लिकेशन बनाते हैं, तो सभी मॉड्यूल और थीम को NuGet और NPM पैकेज के रूप में उपयोग किया जाता है। इसलिए, नया संस्करण उपलब्ध होने पर आप आसानी से संकुल को अपग्रेड कर सकते हैं।", + "HowToUpgradeExplanation2": "मानक NuGet / NPM अपग्रेड के अलावा, ABP CLI एक अपडेट कमांड प्रदान करता है जो आपके समाधान में सभी एबीपी से संबंधित पैकेजों को स्वचालित रूप से ढूंढता है और उन्हें अपग्रेड करता है।", + "DatabaseSupport": "कौन से डेटाबेस सिस्टम समर्थित हैं?", + "DatabaseSupportExplanation": "ABP फ्रेमवर्क स्वयं ही डेटाबेस अज्ञेयवादी है और अपनी प्रकृति के अनुसार किसी भी डेटाबेस प्रदाता के साथ काम कर सकता है। वर्तमान में कार्यान्वित प्रदाताओं की सूची के लिए डेटा एक्सेस दस्तावेज़ देखें।", + "UISupport": "कौन से UI फ्रेमवर्क समर्थित हैं?", + "Supported": "समर्थित", + "UISupportExplanation": "ABP फ्रेमवर्क स्वयं UI फ्रेमवर्क अज्ञेयवादी है और किसी भी UI फ्रेमवर्क के साथ काम कर सकता है। हालाँकि, सभी UI फ्रेमवर्क के लिए स्टार्टअप टेम्प्लेट, मॉड्यूल UI और थीम लागू नहीं किए गए थे। UI विकल्पों की अप-टू-डेट सूची के लिए आरंभ किया गया दस्तावेज़ देखें।", + "MicroserviceSupport": "क्या यह सूक्ष्म सेवा वास्तुकला का समर्थन करता है?", + "MicroserviceSupportExplanation1": "एबीपी ढांचे का एक प्रमुख लक्ष्य सूक्ष्म सेवा समाधान बनाने के लिए एक सुविधाजनक बुनियादी ढांचा प्रदान करना है। यह समझने के लिए कि यह माइक्रो-सर्विस सिस्टम बनाने में कैसे मदद करता है, यह समझने के लिए माइक्रो-सर्विस आर्किटेक्चर दस्तावेज़ देखें।", + "MicroserviceSupportExplanation2": "सभी एबीपी कमर्शियल मॉड्यूल्स को मॉड्यूल डेवलपमेंट बेस्ट प्रैक्टिस दस्तावेज़ का पालन करके माइक्रो-सर्विस परिनियोजन परिदृश्य (अपने एपीआई और डेटाबेस के साथ) का समर्थन करने के लिए डिज़ाइन किया गया है।", + "MicroserviceSupportExplanation3": "हम आपको अपना स्वयं का समाधान बनाने में मदद करने के लिए एक माइक्रो-सेवा वास्तुकला कार्यान्वयन को प्रदर्शित करने वाला एक नमूना माइक्रो-सर्विस डेमो समाधान प्रदान करते हैं।", + "MicroserviceSupportExplanation4": "तो, संक्षिप्त उत्तर \" हां है, यह सूक्ष्म सेवा वास्तुकला का समर्थन करता है \"।", + "MicroserviceSupportExplanation5": "हालाँकि, एक माइक्रो-सर्विस सिस्टम एक समाधान है और हर समाधान में अलग-अलग आवश्यकताएं, नेटवर्क टोपोलॉजी, संचार परिदृश्य, प्रमाणीकरण संभावनाएं, डेटाबेस पृथक्करण / साझा करने के निर्णय, रनटाइम कॉन्फ़िगरेशन, 3 पार्टी सिस्टम एकीकरण और कई और अधिक होंगे।", + "MicroserviceSupportExplanation6": "ABP फ्रेमवर्क और ABP कमर्शियल आपको अपने स्वयं के समाधान का निर्माण करने में मदद करने के लिए सूक्ष्म सेवा परिदृश्य, सूक्ष्म सेवा संगत मॉड्यूल, नमूने और प्रलेखन के लिए बुनियादी ढाँचा प्रदान करता है। लेकिन अपने सपनों के समाधान को सीधे आपके लिए पहले से डाउनलोड करने की उम्मीद न करें। आपको इसे समझने और अपनी आवश्यकताओं के आधार पर कुछ हिस्सों को एक साथ लाने की आवश्यकता होगी।", + "WhereCanIDownloadSourceCode": "मैं स्रोत-कोड कहां से डाउनलोड कर सकता हूं?", + "WhereCanIDownloadSourceCodeExplanation": "आप एबीपी सूट या एबीपी सीएलआई के माध्यम से सभी एबीपी मॉड्यूल, कोणीय पैकेज और थीम के स्रोत कोड डाउनलोड कर सकते हैं। स्रोत-कोड डाउनलोड कैसे करें? देखें", + "ComputerLimitation": "एबीपी विकसित करते समय एक डेवलपर कितने कंप्यूटरों पर लॉगिन कर सकता है?", + "ComputerLimitationExplanation": "हम विशेष रूप से प्रति व्यक्ति / लाइसेंस प्राप्त डेवलपर के लिए {0} कंप्यूटर की अनुमति देते हैं। जब भी किसी तीसरे मशीन पर एबीपी कमर्शियल उत्पादों को विकसित करने के लिए डेवलपर की आवश्यकता होती है, तो स्थिति को समझाते हुए लाइसेंस@abp.io को एक ई-मेल भेजा जाना चाहिए और फिर हम अपने सिस्टम में उचित आवंटन करेंगे।", + "RefundPolicy": "क्या आपके पास धनवापसी नीति है?", + "RefundPolicyExplanation": "आप अपनी लाइसेंस खरीद के 30 दिन के भीतर धनवापसी का अनुरोध कर सकते हैं। व्यवसाय और उद्यम लाइसेंस प्रकार में स्रोत-कोड डाउनलोड विकल्प होता है, इसलिए व्यापार और उद्यम के लिए धनवापसी उपलब्ध नहीं होती है (और कोई भी लाइसेंस जिसमें स्रोत-कोड प्राप्त करने का अधिकार शामिल होता है)। इसके अलावा, नवीनीकरण और दूसरे लाइसेंस खरीद के लिए कोई भी रिफंड नहीं किया जाता है।", + "HowCanIRefundVat": "मैं VAT कैसे वापस कर सकता हूँ?", + "HowCanIRefundVatExplanation1": "यदि आपने 2 चेकआउट का उपयोग करके भुगतान किया है, तो आप अपने 2 चेकआउट खाते के माध्यम से वैट वापस कर सकते हैं:", + "HowCanIRefundVatExplanation2": "अपने 2 चेकआउट खाते में लॉग इन करें", + "HowCanIRefundVatExplanation3": "उपयुक्त आदेश खोजें और \"रिफंड बेल्ड वैट\" दबाएं (अपनी वैट आईडी दर्ज करें)", + "HowCanIGetMyInvoice": "मैं अपना चालान कैसे प्राप्त कर सकता हूं?", + "HowCanIGetMyInvoiceExplanation": "लाइसेंस खरीदने के लिए 2 भुगतान गेटवे हैं: PayU और 2 चेकआउट। यदि आप 2Checkout गेटवे के माध्यम से अपना लाइसेंस खरीदते हैं, तो यह आपके ईमेल पते पर पीडीएफ चालान भेजता है, देखें 2 चेकआउट चालान। यदि आप पेयू गेटवे या बैंक वायर ट्रांसफर के माध्यम से खरीदते हैं, तो हम आपका चालान तैयार करेंगे और भेजेंगे। आप अपने चालान का अनुरोध संगठन प्रबंधन पृष्ठ से कर सकते हैं", + "Forum": "मंच", + "SupportExplanation": "ABP कमर्शियल लाइसेंस एक टीम द्वारा प्रीमियम फ़ोरम सपोर्ट प्रदान करता है जिसमें ABP फ्रेमवर्क विशेषज्ञ होते हैं।", + "PrivateTicket": "निजी टिकट", + "PrivateTicketExplanation": "एंटरप्राइज लाइसेंस में ई-मेल और टिकट प्रणाली के साथ एक निजी सहायता भी शामिल है।", + "AbpSuiteExplanation1": "ABP सुइट आपको कुछ ही मिनटों में वेब पेज बनाने की अनुमति देता है। यह .NET कोर ग्लोबल टूल है जिसे कमांड लाइन से इंस्टॉल किया जा सकता है।", + "AbpSuiteExplanation2": "यह एक नया ABP समाधान बना सकता है, डेटाबेस से फ्रंट-एंड तक CRUD पेज बना सकता है। तकनीकी ओवरव्यू के लिए दस्तावेज़ देखें", + "FastEasy": "तेज और आसान", + "AbpSuiteExplanation3": "ABP सुइट आपको आसानी से CRUD पेज बनाने की अनुमति देता है। आपको बस अपनी इकाई और उसके गुणों को परिभाषित करने की आवश्यकता है, बाकी को आप के लिए एबीपी सूट करने दें! एबीपी सूट कुछ ही सेकंड में आपके सीआरयूडी पृष्ठ के लिए सभी आवश्यक कोड उत्पन्न करता है। यह Angular, MVC और Blazor यूजर इंटरफेस को सपोर्ट करता है।", + "RichOptions": "अमीर विकल्प", + "AbpSuiteExplanation4": "ABP सुइट रेजर पेज और Angular । यह MongoDB जैसे कई डेटाबेस का समर्थन करता है और सभी डेटाबेस EntityFramework Core <द्वारा समर्थित है / strong> (MS SQL सर्वर, Oracle, MySql, PostgreSQL और )।", + "AbpSuiteExplanation5": "अच्छी बात यह है कि, आपको उन विकल्पों के बारे में चिंता करने की ज़रूरत नहीं है। एबीपी सूट आपके प्रोजेक्ट के प्रकार को समझता है और आपकी परियोजना के लिए कोड बनाता है और उत्पन्न कोड को आपके प्रोजेक्ट में सही जगह पर रखता है।", + "SourceCode": "सोर्स कोड", + "AbpSuiteExplanation6": "ABP स्वीट आपके लिए सोर्स कोड जेनरेट करता है! यह वेब पेज जनरेट करने के लिए मैजिक फाइल्स जेनरेट नहीं करता है। एबीपी सूट इकाई, रिपोजिटरी, एप्लीकेशन सर्विस, कोड फर्स्ट माइग्रेशन, जावास्क्रिप्ट / टाइपस्क्रिप्ट और सीएसएचटीएमएल / एचटीएमएल और आवश्यक इंटरफेस के लिए भी स्रोत कोड उत्पन्न करता है। ABP Suite सॉफ्टवेयर डेवलपमेंट के बेस्ट प्रैक्टिसेस के अनुसार कोड भी तैयार करता है, इसलिए आपको जनरेट किए गए कोड की गुणवत्ता के बारे में चिंता करने की आवश्यकता नहीं है।", + "AbpSuiteExplanation7": "चूँकि आपके पास सही एप्लिकेशन लेयर्स में जेनरेट किए गए CRUD पेज के बिल्डिंग ब्लॉक्स का सोर्स कोड है, आप आसानी से सोर्स कोड को संशोधित कर सकते हैं और अपने कस्टम / bussiness लॉजिक को जेनरेट कोड में इंजेक्ट कर सकते हैं।", + "CrossPlatform": "क्रास प्लेटफार्म", + "AbpSuiteExplanation8": "ABP सुइट .NET .NET के साथ बनाया गया है और यह क्रॉस प्लेटफॉर्म है। यह आपके स्थानीय कंप्यूटर पर एक वेब एप्लिकेशन के रूप में चलता है। आप इसे Windows , Mac और Linux पर चला सकते हैं", + "OtherFeatures": "अन्य सुविधाओं", + "OtherFeatures1": "अपडेट्स NuGet और NPM पैकेज आपके समाधान पर आसानी से।", + "OtherFeatures2": "खरोंच से पहले से ही उत्पन्न पृष्ठों को पुन: उत्पन्न करता है।", + "OtherFeatures3": "नए समाधान बनाता है", + "ThanksForCreatingProject": "अपना प्रोजेक्ट बनाने के लिए धन्यवाद!", + "HotToRunSolution": "अपना हल कैसे चलाएं?", + "HotToRunSolutionExplanation": "अपने समाधान को कॉन्फ़िगर करने और चलाने का तरीका जानने के लिए आरंभ किया गया दस्तावेज़ देखें।", + "GettingStarted": "शुरू करना", + "WebAppDevTutorial": "वेब ऐप देव ट्यूटोरियल", + "WebAppDevTutorialExplanation": "कदम विकास नमूना द्वारा एक कदम के लिए वेब अनुप्रयोग विकास ट्यूटोरियल दस्तावेज़ देखें।", + "Document": "डाक्यूमेंट", + "UsingABPSuiteToCURD": "CRUD पेज जनरेशन और टूलिंग के लिए ABP सूट का उपयोग करना", + "SeeABPSuiteDocument": "ABP सुइट का उपयोग जानने के लिए ABP सुइट दस्तावेज़ देखें।", + "AskQuestionsOnSupport": "आप एबीपी कमर्शियल सपोर्ट पर सवाल पूछ सकते हैं।", + "Documentation": "प्रलेखन", + "SeeModulesDocument": "सभी वाणिज्यिक (समर्थक) मॉड्यूल और उनके दस्तावेजों की सूची के लिए मॉड्यूल दस्तावेज़ देखें।", + "Pricing": "मूल्य निर्धारण", + "PricingExplanation": "आज अपनी व्यावसायिक आवश्यकताओं के लिए सुविधाओं और कार्यक्षमता का चयन करें। जैसे ही आपका व्यवसाय बढ़ता है, आसानी से अपग्रेड करें।", + "Team": "टीम", + "Business": "व्यापार", + "Enterprise": "उद्यम", + "Custom": "रिवाज", + "IncludedDeveloperLicenses": "डेवलपर लाइसेंस शामिल हैं", + "CustomLicenceOrAdditionalServices": "कस्टम लाइसेंस या अतिरिक्त सेवाओं की आवश्यकता है?", + "CustomOrVolumeLicense": "कस्टम या वॉल्यूम लाइसेंस", + "LiveTrainingSupport": "लाइव प्रशिक्षण और समर्थन", + "AndMore": "और अधिक", + "AdditionalDeveloperLicense": "अतिरिक्त डेवलपर लाइसेंस", + "ProjectCount": "प्रोजेक्ट की गिनती", + "AllProModules": "सभी प्रो मॉड्यूल", + "AllProThemes": "सभी प्रो थीम", + "AllProStartupTemplates": "सभी प्रो स्टार्टअप टेम्प्लेट", + "SourceCodeOfAllModules": "सभी मॉड्यूल का स्रोत कोड", + "SourceCodeOfAllThemes": "सभी विषयों का स्रोत कोड", + "PerpetualLicense": "हमेशा के लिए लाइसेंस", + "UnlimitedServerDeployment": "असीमित सर्वर की तैनाती", + "YearUpgrade": "1 साल का उन्नयन", + "YearPremiumForumSupport": "1 साल का प्रीमियम फोरम सपोर्ट", + "ForumSupportIncidentCountYear": "फोरम समर्थन घटना गिनती / वर्ष", + "PrivateTicketEmailSupport": "निजी टिकट और ईमेल समर्थन", + "BuyNow": "अभी खरीदें", + "PayViaAmexCard": "मैं अपने AMEX कार्ड के माध्यम से कैसे भुगतान कर सकता हूं?", + "PayViaAmexCardDescription": "डिफ़ॉल्ट भुगतान गेटवे 'Iyzico' सुरक्षा उपायों के कारण कुछ AMEX क्रेडिट कार्डों को अस्वीकार कर सकता है। इस मामले में, आप वैकल्पिक भुगतान गेटवे '2 चेकआउट' के माध्यम से भुगतान कर सकते हैं।", + "ThankYou": "धन्यवाद", + "InvalidReCaptchaErrorMessage": "ReCAPTCHA को सत्यापित करने में एक त्रुटि हुई थी। कृपया पुन: प्रयास करें।" + } +} \ No newline at end of file diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/it.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/it.json new file mode 100644 index 0000000000..766702a92b --- /dev/null +++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/it.json @@ -0,0 +1,296 @@ +{ + "culture": "it", + "texts": { + "OrganizationManagement": "Gestione dell'organizzazione", + "OrganizationList": "Elenco delle organizzazioni", + "Volo.AbpIo.Commercial:010003": "Non sei il proprietario di questa organizzazione!", + "OrganizationNotFoundMessage": "Nessuna organizzazione trovata!", + "DeveloperCount": "Sviluppatori allocati / totali", + "QuestionCount": "Domande rimanenti / totali", + "Unlimited": "Illimitato", + "Owners": "Proprietari", + "AddMember": "Aggiungi membro", + "AddOwner": "Aggiungi proprietario", + "AddDeveloper": "Aggiungi sviluppatore", + "UserName": "Nome utente", + "Name": "Nome", + "EmailAddress": "Indirizzo e-mail", + "Developers": "Sviluppatori", + "LicenseType": "Tipo di licenza", + "Manage": "Gestire", + "StartDate": "Data d'inizio", + "EndDate": "Data di fine", + "Modules": "Moduli", + "LicenseExtendMessage": "La data di fine della tua licenza è estesa a {0}", + "LicenseUpgradeMessage": "La tua licenza è stata aggiornata a {0}", + "LicenseAddDeveloperMessage": "{0} sviluppatori aggiunti alla tua licenza", + "Volo.AbpIo.Commercial:010004": "Impossibile trovare l'utente specificato! L'utente deve essere già registrato.", + "MyOrganizations": "Le mie organizzazioni", + "ApiKey": "Chiave API", + "UserNameNotFound": "Nessun utente con nome utente {0}", + "SuccessfullyAddedToNewsletter": "Grazie per esserti iscritto alla nostra newsletter!", + "MyProfile": "Il mio profilo", + "EmailNotValid": "Si prega di inserire un indirizzo email valido.", + "JoinOurMarketingNewsletter": "Iscriviti alla nostra newsletter di marketing", + "WouldLikeToReceiveMarketingMaterials": "Vorrei ricevere materiale di marketing come offerte di prodotti e offerte speciali.", + "StartUsingYourLicenseNow": "Inizia subito a usare la tua licenza!", + "WelcomePage": "Pagina di benvenuto", + "UnsubscriptionExpireEmail": "Annulla l'iscrizione alle e-mail di promemoria della data di scadenza della licenza", + "UnsubscribeLicenseExpireEmailReminderMessage": "Questa sottoscrizione e-mail contiene solo il promemoria della data di scadenza della licenza.", + "UnsubscribeFromLicenseExpireEmails": "Se non desideri ricevere le e-mail sulla data di scadenza della licenza, puoi annullare l'iscrizione in qualsiasi momento lo desideri.", + "Unsubscribe": "Annulla l'iscrizione", + "NotOrganizationMember": "Non sei membro di nessuna organizzazione.", + "UnsubscribeLicenseExpirationEmailSuccessTitle": "Iscrizione annullata con successo", + "UnsubscribeLicenseExpirationEmailSuccessMessage": "Non riceverai più email di promemoria della data di scadenza della licenza.", + "IndexPageHeroSection": " Una completa piattaforma di sviluppo web integrata framework ", + "AbpCommercialShortDescription": "ABP Commercial fornisce moduli applicativi predefiniti, strumenti per lo sviluppo rapido di applicazioni, temi dell'interfaccia utente professionale, supporto premium e altro ancora.", + "LiveDemo": "Dimostrazione dal vivo", + "GetLicence": "Ottieni una licenza", + "Application": "Applicazione", + "StartupTemplates": "Modelli di avvio", + "Startup": "Avviare", + "Templates": "Modelli", + "Developer": "Sviluppatore", + "Tools": "Utensili", + "Premium": "Premium", + "PremiumSupport": "Supporto premium", + "PremiumForumSupport": "Supporto forum premium", + "UI": "UI", + "Themes": "Temi", + "JoinOurNewsletter": "Iscriviti alla nostra newsletter", + "Send": "Spedire", + "Learn": "Imparare", + "AdditionalServices": "Servizi aggiuntivi", + "WhatIsABPFramework": "QUAL È IL QUADRO ABP?", + "OpenSourceBaseFramework": "Framework di base open source", + "ABPFrameworkExplanation": "

ABP Commercial si basa su ABP Framework, un framework per applicazioni web open source e guidato dalla comunità per ASP.NET Core.

ABP Framework fornisce un'eccellente infrastruttura per la scrittura gestibile ed estensibile e codice testabile con best practice.

Costruito e integrato in strumenti popolari che già conosci. Bassa curva di apprendimento, facile adattamento, sviluppo confortevole.

", + "Modular": "Modulare", + "MicroserviceCompatible": "Compatibile con microservizi", + "DomainDrivenDesignInfrastructure": "Infrastruttura di progettazione basata sul dominio", + "MultiTenancy": "Multi-Tenancy", + "DistributedMessaging": "Messaggistica distribuita", + "DynamicProxying": "Proxying dinamico", + "BackgroundJobs": "Lavori in background", + "AuditLogging": "Registrazione di audit", + "BLOBStoring": "Archiviazione BLOB", + "BundlingMinification": "Raggruppamento e minimizzazione", + "AdvancedLocalization": "Localizzazione avanzata", + "ManyMore": "Molti altri", + "ExploreTheABPFramework": "Esplora il framework ABP", + "WhyUseTheABPCommercial": "Perché utilizzare lo spot pubblicitario ABP?", + "WhyUseTheABPCommercialExplanation": "

La creazione di applicazioni Web di livello aziendale può essere complessa e richiede tempo.

ABP Commercial offre l'infrastruttura di base perfetta necessaria per tutti i moderni ASP.NET Core di livello aziendale soluzioni basate. Dalla progettazione all'implementazione, l'intero ciclo di sviluppo è potenziato dalle funzionalità e dai moduli integrati di ABP.

", + "StartupTemplatesShortDescription": "I modelli di avvio ti consentono di avviare rapidamente il tuo progetto in pochi secondi.", + "UIFrameworksOptions": "Opzioni dei framework dell'interfaccia utente;", + "DatabaseProviderOptions": "Opzioni del provider di database;", + "PreBuiltApplicationModules": "Moduli applicativi predefiniti", + "PreBuiltApplicationModulesShortDescription": "I requisiti delle applicazioni più comuni sono già stati sviluppati per te come moduli riutilizzabili.", + "Account": "account", + "Blogging": "Blogging", + "Identity": "Identità", + "IdentityServer": "Identity Server", + "Saas": "Saas", + "LanguageManagement": "Gestione della lingua", + "TextTemplateManagement": "Gestione dei modelli di testo", + "See All Modules": "SeeAllModules", + "ABPSuite": "ABP Suite", + "AbpSuiteShortDescription": "ABP Suite è uno strumento complementare all'ABP Commercial.", + "AbpSuiteExplanation": "Ti consente di creare pagine web in pochi minuti. È uno strumento .NET Core Global che può essere installato dalla riga di comando. Può creare una nuova soluzione ABP, generare pagine CRUD dal database al front-end.", + "Details": "Dettagli", + "LeptonTheme": "Tema Lepton", + "ProfessionalModernUIThemes": "Temi dell'interfaccia utente moderni e professionali", + "LeptonThemeExplanation": "Lepton fornisce una gamma di temi di amministrazione Bootstrap che fungono da solida base per qualsiasi progetto che richieda dashboard di amministrazione.", + "DefaultTheme": "Tema predefinito", + "MaterialTheme": "Tema materiale", + "Default2Theme": "Tema predefinito 2", + "DarkTheme": "Tema scuro", + "DarkBlueTheme": "Tema blu scuro", + "LightTheme": "Tema chiaro", + "ProudToWorkWith": "Orgoglioso di lavorare con", + "OurConsumers": "Centinaia di aziende e sviluppatori in oltre 50 paesi in tutto il mondo si affidano a ABP Commercial.", + "JoinOurConsumers": "Unisciti a loro e crea prodotti sorprendenti velocemente.", + "AdditionalServicesExplanation": "Hai bisogno di servizi aggiuntivi o personalizzati? Noi e i nostri partner possiamo fornire; ", + "CustomProjectDevelopment": "Sviluppo di progetti personalizzati", + "CustomProjectDevelopmentExplanation": "Sviluppatori dedicati per i tuoi progetti personalizzati.", + "PortingExistingProjects": "Porting di progetti esistenti", + "PortingExistingProjectsExplanation": "Migrazione dei tuoi progetti legacy alla piattaforma ABP.", + "LiveSupport": "Supporto dal vivo", + "LiveSupportExplanation": "Opzione di supporto remoto dal vivo quando ne hai bisogno.", + "Training": "Formazione", + "TrainingExplanation": "Formazione dedicata per i tuoi sviluppatori.", + "OnBoarding": "Onboarding", + "OnBoardingExplanation": "Aiuta a configurare i tuoi ambienti di sviluppo, CI e CD.", + "PrioritizedTechnicalSupport": "Assistenza tecnica prioritaria", + "PremiumSupportExplanation": "Oltre al grande supporto della comunità del framework ABP, il nostro team di supporto risponde alle domande tecniche e ai problemi degli utenti commerciali con alta priorità.", + "SeeTheSupportOptions": "Vedi le opzioni di supporto", + "Contact": "Contatto", + "TellUsWhatYouNeed": "Dicci di cosa hai bisogno.", + "YourMessage": "Il tuo messaggio", + "YourFullName": "Il tuo nome completo", + "EmailField": "Indirizzo e-mail", + "YourEmailAddress": "Il tuo indirizzo di posta elettronica", + "HowMayWeHelpYou": "Come possiamo aiutarti?", + "SendMessage": "Invia messaggio", + "Success": "Successo", + "WeWillReplyYou": "Abbiamo ricevuto il tuo messaggio e ti contatteremo a breve.", + "GoHome": "Andare a casa", + "CreateLiveDemo": "Crea demo live", + "RegisterToTheNewsletter": "Registrati alla newsletter per ricevere informazioni su ABP.IO, comprese le nuove versioni ecc.", + "EnterYourEmailOrLogin": "Inserisci il tuo indirizzo e-mail per creare la tua demo o
Accedi utilizzando il tuo account esistente.", + "ApplicationTemplate": "Modello di applicazione", + "ApplicationTemplateExplanation": "Il modello di avvio dell'applicazione viene utilizzato per creare una nuova applicazione web.", + "EfCoreProvider": "Entity Framework (supporta SQL Server, MySQL, PostgreSQL, Oracle e altri )", + "AlreadyIncludedInTemplateModules": "I seguenti moduli sono già inclusi e configurati in questo modello:", + "ApplicationTemplateArchitecture": "Questo modello di applicazione supporta anche un'architettura a più livelli in cui il livello dell'interfaccia utente, il livello API e il servizio di autenticazione sono fisicamente separati.", + "SeeTheGuideOrGoToTheLiveDemo": "Consulta la guida per sviluppatori per informazioni tecniche su questo modello o vai alla demo live.", + "DeveloperGuide": "Guida per sviluppatori", + "ModuleTemplate": "Modello di modulo", + "ModuleTemplateExplanation1": "Vuoi creare un modulo e riutilizzarlo in diverse applicazioni? Questo modello di avvio prepara tutto per iniziare a creare un modulo dell'applicazione riutilizzabile o un microservizio .", + "ModuleTemplateExplanation2": "

Puoi supportare uno o più framework UI, uno o più provider di database per un singolo modulo. Il modello di avvio è configurato per eseguire e testare il modulo in un'applicazione minima oltre all'unità e all'infrastruttura di test di integrazione.

Consulta la guida per sviluppatori per informazioni tecniche su questo modello.

", + "WithAllStyleOptions": "con tutte le opzioni di stile", + "Demo": "Demo", + "SeeAllModules": "Vedi tutti i moduli", + "ABPCLIExplanation": "ABP CLI (Command Line Interface) è uno strumento a riga di comando per eseguire alcune operazioni comuni per soluzioni basate su ABP.", + "ABPSuiteEasilyCURD": "ABP Suite è uno strumento che ti permette di creare facilmente pagine CRUD", + "WeAreHereToHelp": "Siamo qui per Aiuto ", + "BrowseOrAskQuestion": "Puoi sfogliare i nostri argomenti della guida o cercare nelle domande frequenti oppure puoi farci una domanda utilizzando il modulo di contatto .", + "SearchQuestionPlaceholder": "Cerca nelle domande frequenti", + "WhatIsTheABPCommercial": "Cos'è l'ABP Commercial?", + "WhatAreDifferencesThanAbpFramework": "Quali sono le differenze tra ABP Framework open source e ABP Commercial?", + "ABPCommercialExplanation": "ABP Commercial è un insieme di moduli, strumenti, temi e servizi premium basati sul framework ABP open source. ABP Commercial è sviluppato e supportato dallo stesso team dietro il framework ABP.", + "WhatAreDifferencesThanABPFrameworkExplanation": "

ABP framework è un framework di sviluppo di applicazioni compatibile con micro-servizi per ASP.NET Core modulare. Fornisce un'architettura completa e una solida infrastruttura per farti concentrare sul tuo codice aziendale piuttosto che ripetere te stesso per ogni nuovo progetto. Si basa sulle migliori pratiche di sviluppo software e su strumenti popolari che già conosci.

Il framework ABP è completamente gratuito, open source e guidato dalla comunità. Fornisce inoltre un tema gratuito e alcuni moduli predefiniti (ad es. Gestione delle identità e gestione dei tenant).

", + "VisitTheFrameworkVSCommercialDocument": "Visita il seguente link, per ulteriori informazioni {1} ", + "ABPCommercialFollowingBenefits": "ABP Commercial aggiunge i seguenti vantaggi al framework ABP;", + "Professional": "Professionale", + "UIThemes": "Temi dell'interfaccia utente", + "EnterpriseModules": " moduli applicativi preconfigurati, ricchi di funzionalità (ad es. Gestione di Identity Server, gestione SaaS, gestione della lingua)", + "ToolingToSupport": "Strumenti per supportare la produttività dello sviluppo (ad es. ABP Suite )", + "PremiumSupportLink": "Supporto Premium premium", + "WhatDoIDownloadABPCommercial": "Cosa devo scaricare quando acquisto ABP Commercial?", + "CreateUnlimitedSolutions": "Dopo aver acquistato una licenza commerciale ABP, sarai in grado di creare soluzioni illimitate come descritto nel documento Guida introduttiva .", + "ABPCommercialSolutionExplanation": "Quando crei una nuova applicazione, ottieni una soluzione Visual Studio (un modello di avvio) in base alle tue preferenze. La soluzione scaricata ha moduli e temi commerciali già installati e configurati per te. Puoi rimuovere un modulo preinstallato o aggiungere un altro modulo, se lo desideri. Tutti i moduli e temi vengono usati come pacchetti NuGet / NPM per impostazione predefinita.", + "StartDevelopWithTutorials": "La soluzione scaricata è ben progettata e documentata. Puoi iniziare a sviluppare il tuo codice aziendale basato su di esso seguendo i tutorial ", + "TryTheCommercialDemo": "Puoi provare la demo per vedere un'applicazione di esempio creata utilizzando il modello di avvio di ABP Commercial.", + "HowManyProducts": "Quanti prodotti / soluzioni differenti posso costruire utilizzando ABP Commercial?", + "HowManyProductsExplanation": "Non ci sono limiti per creare un progetto ABP. Puoi creare tutti i progetti che desideri, svilupparli e caricarli su server diversi.", + "HowManyDevelopers": "Quanti sviluppatori possono lavorare su ABP Commercial?", + "HowManyDevelopersExplanation": "Le licenze commerciali ABP sono per sviluppatore. Diversi tipi di licenza hanno diversi limiti per sviluppatori. Tuttavia, puoi aggiungere più sviluppatori a qualsiasi tipo di licenza ogni volta che ne hai bisogno. Consulta la pagina dei prezzi per i tipi di licenza, i limiti per gli sviluppatori e i costi aggiuntivi per gli sviluppatori.", + "ChangingLicenseType": "Posso cambiare il mio tipo di licenza in futuro?", + "ChangingLicenseTypeExplanation": "Puoi sempre aggiungere nuovi sviluppatori con lo stesso tipo di licenza. Vedi anche \"Quanti sviluppatori possono lavorare su ABP Commercial?\". Puoi anche passare a una licenza superiore pagando la differenza di prezzo calcolata. Quando esegui l'aggiornamento a un piano di licenza superiore, ottieni i vantaggi del nuovo piano, ma l'aggiornamento della licenza non modifica la data di scadenza della licenza.", + "LicenseExtendUpgradeDiff": "Qual è la differenza tra estensione della licenza e aggiornamento?", + "LicenseExtendUpgradeDiffExplanation": " Estensione: estendendo / rinnovando la tua licenza, continuerai a ricevere supporto premium e a ricevere aggiornamenti importanti per moduli e temi. Inoltre, potrai continuare a creare nuovi progetti. E sarai ancora in grado di utilizzare ABP Suite che accelera il tuo sviluppo.
Upgrade: aggiornando la tua licenza, promuoverai un piano di licenza superiore che ti consentirà di ottenere ulteriori vantaggi . Consulta la tabella di confronto delle licenze per verificare le differenze tra i piani di licenza. D'altra parte, quando esegui l'upgrade, la data di scadenza della licenza non cambierà! Per estendere la data di fine della licenza, è necessario estendere la licenza.", + "LicenseRenewalCost": "Qual è il costo del rinnovo della licenza dopo 1 anno?", + "LicenseRenewalCostExplanation": "La tariffa di rinnovo (estensione) di tutte le licenze perpetue ABP Commercial è {0} del prezzo di listino della licenza. Il prezzo di rinnovo della licenza Team standard è $ {1}, la licenza Business standard è $ {2} e la licenza Enterprise standard è $ {3}. Se sei già un cliente, accedi al tuo account per esaminare i prezzi di rinnovo disponibili.", + "HowDoIRenewMyLicense": "Come rinnovo la mia licenza?", + "HowDoIRenewMyLicenseExplanation": "Puoi rinnovare la licenza accedendo alla pagina di gestione dell'organizzazione . Per poter usufruire delle nostre tariffe scontate di rinnovo anticipato, assicurati di rinnovare prima della scadenza della licenza. Tuttavia, non preoccuparti di non sapere quando si chiude la tua opportunità di rinnovo anticipato. Riceverai 2 e-mail di promemoria prima della scadenza dell'abbonamento. Li invieremo a 30 giorni, 7 giorni prima della scadenza.", + "IsSourceCodeIncluded": "La mia licenza include il codice sorgente dei moduli e dei temi commerciali?", + "IsSourceCodeIncludedExplanation1": "Dipende dal tipo di licenza che hai acquistato:", + "IsSourceCodeIncludedExplanation2": " Team : la soluzione utilizza i moduli e i temi come pacchetti NuGet e NPM. Non include il loro codice sorgente. In questo modo, puoi aggiornare facilmente questi moduli e temi ogni volta che è disponibile una nuova versione. Tuttavia, non è possibile ottenere il codice sorgente dei moduli e dei temi.", + "IsSourceCodeIncludedExplanation3": " Business / Enterprise : oltre alla licenza Team, puoi scaricare il codice sorgente di qualsiasi modulo o tema di cui hai bisogno. È anche possibile rimuovere i riferimenti al pacchetto NuGet / NPM per un particolare modulo e aggiungere il relativo codice sorgente direttamente alla soluzione per modificarlo completamente.", + "IsSourceCodeIncludedExplanation4": "

Includere il codice sorgente di un modulo nella tua soluzione ti dà la massima libertà di personalizzare quel modulo. Tuttavia, non sarà possibile aggiornare automaticamente il modulo quando viene rilasciata una nuova versione.

Nessuna delle licenze include il codice sorgente di ABP Suite, che è uno strumento esterno che genera codice per te e assiste al tuo sviluppo.

Vedi la pagina dei prezzi per altre differenze tra i tipi di licenza.

", + "ChangingDevelopers": "Posso cambiare gli sviluppatori registrati della mia organizzazione in futuro?", + "ChangingDevelopersExplanation": "Oltre ad aggiungere nuovi sviluppatori alla tua licenza, puoi anche modificare gli sviluppatori esistenti (puoi rimuovere uno sviluppatore e aggiungerne uno nuovo alla stessa postazione) senza alcun costo aggiuntivo.", + "WhatHappensWhenLicenseEnds": "Cosa succede al termine del periodo di licenza?", + "WhatHappensWhenLicenseEndsExplanation1": "Il tipo di licenza commerciale ABP è licenza perpetua . Dopo la scadenza della licenza, puoi continuare a sviluppare il tuo progetto. E non sei obbligato a rinnovare la tua licenza. La tua licenza viene fornita con un anno di aggiornamenti e piano di supporto pronto all'uso. Per continuare a ricevere nuove funzionalità, miglioramenti delle prestazioni, correzioni di bug, supporto e continuare a utilizzare ABP Suite, assicurati di rinnovare il tuo piano ogni anno. Quando la tua licenza scade, non sarai in grado di ottenere più dei seguenti vantaggi;", + "WhatHappensWhenLicenseEndsExplanation2": "Non è possibile creare nuove soluzioni utilizzando ABP Commercial, ma è possibile continuare a sviluppare le applicazioni esistenti per sempre.", + "WhatHappensWhenLicenseEndsExplanation3": "Sarai in grado di ottenere aggiornamenti per i moduli e i temi nella tua versione MAJOR. Per esempio; se stai usando la v3.2.0 di un modulo, puoi comunque ottenere gli aggiornamenti per la v3.x.x (v3.3.0, v3.5.2 ... ecc.) di quel modulo. Ma non puoi ottenere aggiornamenti per la prossima versione principale (come v4.x, v5.x)", + "WhatHappensWhenLicenseEndsExplanation4": "Non è possibile installare nuovi moduli e temi aggiunti alla piattaforma ABP Commercial al termine della licenza.", + "WhatHappensWhenLicenseEndsExplanation5": "Non è possibile utilizzare ABP Suite.", + "WhatHappensWhenLicenseEndsExplanation6": "Non puoi più ottenere l ' assistenza premium .", + "WhatHappensWhenLicenseEndsExplanation7": "Puoi rinnovare l'abbonamento se desideri continuare a usufruire di questi vantaggi. C'è uno sconto del 20% quando rinnovi l'abbonamento.", + "WhenShouldIRenewMyLicense": "Quando devo rinnovare la mia licenza?", + "WhenShouldIRenewMyLicenseExplanation1": "Se rinnovi la licenza entro 1 mese dalla scadenza della licenza, verrà applicato uno sconto del 20% sul prezzo totale della licenza.", + "WhenShouldIRenewMyLicenseExplanation2": "Se rinnovi la licenza dopo 1 mese dalla data di scadenza della licenza, il prezzo di rinnovo sarà lo stesso del prezzo di acquisto della licenza e non ci saranno sconti per il rinnovo.", + "TrialPlan": "Hai un piano di prova?", + "TrialPlanExplanation": "Per ora, ABP Commercial non ha un piano di prova. Per le licenze Team forniamo una garanzia di rimborso di 30 giorni. Puoi richiedere un rimborso solo nei primi 30 giorni. Per le licenze Business ed Enterprise, forniamo un rimborso del 60% in 30 giorni. Questo perché le licenze Business ed Enterprise includono il codice sorgente completo di tutti i moduli e i temi.", + "DoYouAcceptBankWireTransfer": "Accettate bonifici bancari?", + "DoYouAcceptBankWireTransferExplanation": "Sì, accettiamo bonifico bancario.
Dopo aver inviato l'importo della licenza tramite bonifico bancario, inviaci la ricevuta e il tipo di licenza richiesto tramite e-mail.
Informazioni sul nostro conto bancario internazionale:", + "HowToUpgrade": "Come aggiornare le applicazioni esistenti quando è disponibile una nuova versione?", + "HowToUpgradeExplanation1": "Quando crei una nuova applicazione utilizzando ABP Commercial, tutti i moduli e il tema vengono utilizzati come pacchetti NuGet e NPM. Quindi, puoi facilmente aggiornare i pacchetti quando è disponibile una nuova versione.", + "HowToUpgradeExplanation2": "Oltre agli aggiornamenti NuGet / NPM standard, ABP CLI fornisce un comando di aggiornamento che trova e aggiorna automaticamente tutti i pacchetti relativi a ABP nella soluzione.", + "DatabaseSupport": "Quali sistemi di database sono supportati?", + "DatabaseSupportExplanation": "Lo stesso ABP Framework è indipendente dal database e può funzionare con qualsiasi provider di database per sua natura. Consulta il documento di accesso ai dati per un elenco dei fornitori attualmente implementati.", + "UISupport": "Quali framework dell'interfaccia utente sono supportati?", + "Supported": "Supportato", + "UISupportExplanation": "Lo stesso ABP Framework è indipendente dal framework dell'interfaccia utente e può funzionare con qualsiasi framework dell'interfaccia utente. Tuttavia, i modelli di avvio, le interfacce utente dei moduli e i temi non sono stati implementati per tutti i framework dell'interfaccia utente. Consulta il documento introduttivo per l'elenco aggiornato delle opzioni dell'interfaccia utente.", + "MicroserviceSupport": "Supporta l'architettura dei micro-servizi?", + "MicroserviceSupportExplanation1": "Uno degli obiettivi principali del framework ABP è fornire un'infrastruttura conveniente per creare soluzioni di micro-servizi. Consulta il documento sull ' architettura dei micro-servizi per capire come aiuta a creare sistemi di micro-servizi.", + "MicroserviceSupportExplanation2": "Tutti i moduli ABP Commercial sono progettati per supportare scenari di distribuzione di micro-servizi (con la propria API e database) seguendo il documento best practice per lo sviluppo di moduli .", + "MicroserviceSupportExplanation3": "Forniamo una soluzione demo di micro-servizi di esempio che dimostra l'implementazione di un'architettura di micro-servizi per aiutarti a creare la tua soluzione.", + "MicroserviceSupportExplanation4": "Quindi, la risposta breve è \" sì, supporta l'architettura di micro-servizi \".", + "MicroserviceSupportExplanation5": "Tuttavia, un sistema di micro-servizi è una soluzione e ogni soluzione avrà requisiti diversi, topologia di rete, scenari di comunicazione, possibilità di autenticazione, decisioni di separazione / condivisione del database, configurazioni di runtime, integrazioni di sistemi di terze parti e molto altro.", + "MicroserviceSupportExplanation6": "L'ABP Framework e l'ABP Commercial forniscono un'infrastruttura per scenari di micro-servizi, moduli compatibili con micro-servizi, esempi e documentazione per aiutarti a creare la tua soluzione. Ma non aspettarti di scaricare direttamente la soluzione dei tuoi sogni precostruita per te. Dovrai capirlo e riunire alcune parti in base alle tue esigenze.", + "WhereCanIDownloadSourceCode": "Dove posso scaricare il codice sorgente?", + "WhereCanIDownloadSourceCodeExplanation": "È possibile scaricare il codice sorgente di tutti i moduli ABP, pacchetti e temi Angular tramite ABP Suite o ABP CLI. Vedi Come scaricare il codice sorgente? ", + "ComputerLimitation": "Quanti computer può accedere uno sviluppatore durante lo sviluppo di ABP?", + "ComputerLimitationExplanation": "Autorizziamo specificamente {0} computer per singolo sviluppatore / con licenza. Ogni volta che è necessario che uno sviluppatore sviluppi prodotti ABP Commercial su una terza macchina, deve essere inviata un'e-mail a license@abp.io spiegando la situazione e quindi effettueremo l'allocazione appropriata nel nostro sistema.", + "RefundPolicy": "Hai una politica di rimborso?", + "RefundPolicyExplanation": "Puoi richiedere un rimborso entro 30 giorni dall'acquisto della licenza. I tipi di licenza Business ed Enterprise hanno l'opzione di download del codice sorgente, pertanto i rimborsi non sono disponibili per Business ed Enterprise (e qualsiasi licenza che includa il diritto di ricevere il codice sorgente). Inoltre, non vengono effettuati rimborsi per rinnovi e acquisti di seconde licenze.", + "HowCanIRefundVat": "Come posso rimborsare l'IVA?", + "HowCanIRefundVatExplanation1": "Se hai effettuato il pagamento utilizzando 2Checkout, puoi rimborsare l'IVA tramite il tuo account 2Checkout:", + "HowCanIRefundVatExplanation2": "Accedi al tuo account 2Checkout ", + "HowCanIRefundVatExplanation3": "Trova l'ordine appropriato e premi \"Rimborsa IVA tardiva\" (inserisci il tuo numero di partita IVA)", + "HowCanIGetMyInvoice": "Come posso ricevere la mia fattura?", + "HowCanIGetMyInvoiceExplanation": "Esistono 2 gateway di pagamento per l'acquisto di una licenza: PayU e 2Checkout. Se acquisti la tua licenza tramite il gateway 2Checkout, invia la fattura in PDF al tuo indirizzo e-mail, vedi Fatturazione 2Checkout. Se acquisti tramite il gateway PayU o tramite bonifico bancario, prepareremo e invieremo la tua fattura. Puoi richiedere la fattura dalla pagina di gestione dell'organizzazione. ", + "Forum": "Forum", + "SupportExplanation": "Le licenze commerciali di ABP forniscono un supporto forum premium da parte di un team composto dagli esperti di ABP Framework.", + "PrivateTicket": "Biglietto privato", + "PrivateTicketExplanation": "Enterprise License include anche un supporto privato con e-mail e sistema di ticket.", + "AbpSuiteExplanation1": "ABP Suite ti consente di creare pagine web in pochi minuti. È uno strumento .NET Core Global che può essere installato dalla riga di comando.", + "AbpSuiteExplanation2": "Può creare una nuova soluzione ABP, generare pagine CRUD dal database al front-end. Per una panoramica tecnica, vedere il documento ", + "FastEasy": "Veloce e facile", + "AbpSuiteExplanation3": "ABP Suite ti consente di creare facilmente pagine CRUD. Devi solo definire la tua entità e le sue proprietà, lascia che il resto sia ABP Suite per te! ABP Suite genera tutto il codice necessario per la tua pagina CRUD in pochi secondi. Supporta le interfacce utente Angular, MVC e Blazor.", + "RichOptions": "Opzioni ricche", + "AbpSuiteExplanation4": "ABP Suite supporta più opzioni dell'interfaccia utente come Razor Pages e Angular . Supporta anche più database come MongoDB e tutti i database supportati da EntityFramework Core < / strong> (MS SQL Server, Oracle, MySql, PostgreSQL e altro ).", + "AbpSuiteExplanation5": "La cosa buona è che non devi preoccuparti di quelle opzioni. ABP Suite comprende il tipo di progetto e genera il codice per il progetto e inserisce il codice generato nella posizione corretta nel progetto.", + "SourceCode": "Codice sorgente", + "AbpSuiteExplanation6": "ABP Suite genera il codice sorgente per te! Non genera file magici per generare la pagina web. ABP Suite genera il codice sorgente per Entity, Repository, Application Service, Code First Migration, JavaScript / TypeScript e CSHTML / HTML e anche le interfacce necessarie. ABP Suite genera anche il codice in base alle Best Practices di sviluppo software, quindi non devi preoccuparti della qualità del codice generato.", + "AbpSuiteExplanation7": "Dal momento che hai il codice sorgente dei blocchi costitutivi della pagina CRUD generata nei livelli di applicazione corretti, puoi facilmente modificare il codice sorgente e inserire la tua logica personalizzata / aziendale nel codice generato.", + "CrossPlatform": "Piattaforma multipla", + "AbpSuiteExplanation8": "ABP Suite è costruito con .NET Core ed è multipiattaforma. Funziona come un'applicazione web sul tuo computer locale. Puoi eseguirlo su Windows , Mac e Linux ", + "OtherFeatures": "Altre caratteristiche", + "OtherFeatures1": "Aggiorna facilmente i pacchetti NuGet e NPM sulla tua soluzione.", + "OtherFeatures2": "Rigenera le pagine già generate da zero.", + "OtherFeatures3": "Crea nuove soluzioni", + "ThanksForCreatingProject": "Grazie per aver creato il tuo progetto!", + "HotToRunSolution": "Come eseguire la tua soluzione?", + "HotToRunSolutionExplanation": "Vedere il documento introduttivo per apprendere come configurare ed eseguire la soluzione.", + "GettingStarted": "Iniziare", + "WebAppDevTutorial": "Tutorial per sviluppatori di app Web", + "WebAppDevTutorialExplanation": "Vedere il documento tutorial sullo sviluppo di applicazioni Web per un esempio di sviluppo passo passo.", + "Document": "Documento", + "UsingABPSuiteToCURD": "Utilizzo di ABP Suite per la generazione di pagine CRUD e gli strumenti", + "SeeABPSuiteDocument": "Vedere il documento ABP Suite per apprendere l'utilizzo di ABP Suite.", + "AskQuestionsOnSupport": "Puoi porre domande sul supporto commerciale ABP.", + "Documentation": "Documentazione", + "SeeModulesDocument": "Vedere il documento dei moduli per un elenco di tutti i moduli commerciali (pro) e dei relativi documenti.", + "Pricing": "Prezzi", + "PricingExplanation": "Scegli le caratteristiche e le funzionalità di cui la tua azienda ha bisogno oggi. Esegui facilmente l'upgrade man mano che la tua attività cresce.", + "Team": "Squadra", + "Business": "Attività commerciale", + "Enterprise": "Enterprise", + "Custom": "Personalizzato", + "IncludedDeveloperLicenses": "Licenze per sviluppatori incluse", + "CustomLicenceOrAdditionalServices": "Hai bisogno di una licenza personalizzata o di servizi aggiuntivi?", + "CustomOrVolumeLicense": "Licenza personalizzata o multilicenza", + "LiveTrainingSupport": "Formazione e supporto dal vivo", + "AndMore": "e altro ancora", + "AdditionalDeveloperLicense": "Licenza aggiuntiva per sviluppatori", + "ProjectCount": "Conteggio del progetto", + "AllProModules": "Tutti i moduli professionali", + "AllProThemes": "Tutti i temi professionali", + "AllProStartupTemplates": "Tutti i modelli di avvio professionali", + "SourceCodeOfAllModules": "Codice sorgente di tutti i moduli", + "SourceCodeOfAllThemes": "Codice sorgente di tutti i temi", + "PerpetualLicense": "Licenza perpetua", + "UnlimitedServerDeployment": "Distribuzione illimitata del server", + "YearUpgrade": "1 anno di aggiornamento", + "YearPremiumForumSupport": "1 anno di supporto forum premium", + "ForumSupportIncidentCountYear": "Conteggio degli incidenti di supporto del forum / anno", + "PrivateTicketEmailSupport": "Ticket privato e supporto via e-mail", + "BuyNow": "Acquista ora", + "PayViaAmexCard": "Come posso pagare tramite la mia carta AMEX?", + "PayViaAmexCardDescription": "Il gateway di pagamento predefinito \"Iyzico\" potrebbe rifiutare alcune carte di credito AMEX a causa delle misure di sicurezza. In questo caso, puoi pagare tramite il gateway di pagamento alternativo \"2Checkout\".", + "ThankYou": "Grazie", + "InvalidReCaptchaErrorMessage": "Si è verificato un errore durante la verifica di reCAPTCHA. Per favore riprova." + } +} \ No newline at end of file diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/tr.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/tr.json index e49c82c6fd..53781de97e 100644 --- a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/tr.json +++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/tr.json @@ -31,6 +31,34 @@ "SuccessfullyAddedToNewsletter": "Bültenimize abone olduğunuz için teşekkürler!", "MyProfile": "Profilim", "EmailNotValid": "Lütfen uygun bir e-posta adresi giriniz", - "InvalidReCaptchaErrorMessage": "ReCAPTCHA doğrulanırken hata oluştu, lütfen tekrar deneyin." + "InvalidReCaptchaErrorMessage": "ReCAPTCHA doğrulanırken hata oluştu, lütfen tekrar deneyin.", + "CompanyName": "Şirket", + "YourCompanyName": "Şirketiniz", + "FirstName": "Ad", + "LastName": "Soyad", + "Optional": "Opsiyonel", + "YourFirstName": "Adınız", + "YourLastName": "Soyadınız", + "SpecialOffer": "Özel Teklif", + "SpecialOfferMessage": "Acele et! Fiyatlar sınırlı bir süre için geçerlidir.", + "DiscountRequest": "İndirim İsteği", + "DiscountRequestDescribeCustomerQuestion": "Aşağıdakilerden hangisi sizi tanımlar?", + "DiscountRequestStudentEmailMessage": "E-posta Adresi \".edu\" içermelidir.", + "DiscountRequestDeveloperCount": "Kaç geliştiriciye sahipsiniz?", + "DiscountRequestDeveloperCountExceedMessage": "{0}'ten fazla geliştiricisi olan şirketler için indirimli lisans sağlamıyoruz.", + "DiscountRequestOrganizationName": "Şirket/organizasyon/okul adı", + "Website": "İnternet sitesi", + "GithubUsername": "GitHub kullanıcı adı", + "PhoneNumber": "Telefon numarası", + "Country": "Ülke", + "DescribeABPCommercialUsage": "ABP Commercial kullanarak geliştirmeyi planladığınız projeyi tanımlayın", + "DiscountRequestCertifyInformationMessage": "Tüm bilgilerin gerçek ve doğru olduğunu onaylıyorum.", + "DiscountRequestReceived": "İndirim talebinizi aldık.", + "DiscountRequestStatusMessage": "Verdiğiniz bilgileri kontrol ettikten sonra size cevap vereceğiz.", + "MVCOrRazorPages": "MVC (Razor Pages)", + "Angular": "Angular", + "Blazor": "Blazor", + "New": "Yeni", + "MongoDB": "MongoDB" } } \ No newline at end of file diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/zh-Hans.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/zh-Hans.json index e92e55bf6c..5f99be6ba8 100644 --- a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/zh-Hans.json +++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/zh-Hans.json @@ -143,7 +143,7 @@ "ApplicationTemplateArchitecture": "应用程序模板还支持UI,API,身份验证服务器物理分离的分层架构.", "SeeTheGuideOrGoToTheLiveDemo": "查看开发人员指南或者查看在线演示了解更多关于模板的信息.", "DeveloperGuide": "开发人员指南", - "ModuleTemplate": "模块模块", + "ModuleTemplate": "模块模板", "ModuleTemplateExplanation1": "你是否想要创建可在不同应用程序之间重用的模块? 这个启动模板准备好了一切来创建可重用的应用程序模块或微服务.", "ModuleTemplateExplanation2": "

你可以为一个模块支持单个或多个UI框架, 单个或多个数据库提供程序. 除了单元测试和集成测试基础架构外,启动模板被配置为在一个最小的应用程序中运行和测试你的模块.

查看开发人员指南了解有关此模板的技术信息.

", "WithAllStyleOptions": "使用所有的样式选项", @@ -288,8 +288,36 @@ "ForumSupportIncidentCountYear": "论坛支持事件数量/年", "PrivateTicketEmailSupport": "私有票和email支持", "BuyNow": "现在购买", - "PayViaAmexCard": "我如何通过我的AMEX卡付款?", - "PayViaAmexCardDescription": "由于安全措施,默认付款网关“ Iyzico”可能会拒绝某些AMEX信用卡。 在这种情况下,您可以通过备用付款网关“ 2Checkout”付款。", - "InvalidReCaptchaErrorMessage": "验证reCAPTCHA时出错,请重试。" + "PayViaAmexCard": "我如何通过我的AMEX卡付款?", + "PayViaAmexCardDescription": "由于安全措施,默认付款网关'Iyzico'可能会拒绝某些AMEX信用卡. 在这种情况下, 完全可以通过备用付款网关'2Checkout'付款.", + "InvalidReCaptchaErrorMessage": "验证reCAPTCHA时出错,请重试.", + "CompanyName": "公司名称", + "YourCompanyName": "你的公司名称", + "FirstName": "名", + "LastName": "姓", + "Optional": "可选的", + "YourFirstName": "你的名字", + "YourLastName": "你的姓氏", + "SpecialOffer": "特别优惠", + "SpecialOfferMessage": "尽快付款,价格在一定时间内有效.", + "DiscountRequest": "折扣申请", + "DiscountRequestDescribeCustomerQuestion": "以下哪个选项描述了你?", + "DiscountRequestStudentEmailMessage": "Email地址必须包含'edu'.", + "DiscountRequestDeveloperCount": "你有多少开发人员?", + "DiscountRequestDeveloperCountExceedMessage": "对于超过 {0} 开发人员的公司,我们不提供折扣.", + "DiscountRequestOrganizationName": "公司/组织/学校名称", + "Website": "网站", + "GithubUsername": "GitHub用户名", + "PhoneNumber": "手机号", + "Country": "国家", + "DescribeABPCommercialUsage": "描述你基于ABP商业版进行开发的项目", + "DiscountRequestCertifyInformationMessage": "我证明所有的信息都是真实的.", + "DiscountRequestReceived": "我们收到了你的折扣请求.", + "DiscountRequestStatusMessage": "我们会检查你提供的信息并且给你答复.", + "MVCOrRazorPages": "MVC (Razor Pages)", + "Angular": "Angular", + "Blazor": "Blazor", + "New": "新的", + "MongoDB": "MongoDB" } } diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/zh-Hant.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/zh-Hant.json index e39eaba846..a676aa9124 100644 --- a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/zh-Hant.json +++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/zh-Hant.json @@ -25,6 +25,298 @@ "Volo.AbpIo.Commercial:010004": "不能找到指定的使用者! 使用者必須已經註冊.", "MyOrganizations": "我的組織", "ApiKey": "API key", - "UserNameNotFound": "沒有使用者名稱為{0}的使用者" + "UserNameNotFound": "沒有使用者名稱為{0}的使用者", + "SuccessfullyAddedToNewsletter": "感謝你訂閱我們的新聞簡訊!", + "MyProfile": "我的資料", + "EmailNotValid": "請輸入有效的電子郵件地址", + "JoinOurMarketingNewsletter": "加入我們的營銷簡訊", + "WouldLikeToReceiveMarketingMaterials": "我想收到市場營銷資料,例如產品交易和特別優惠.", + "StartUsingYourLicenseNow": "立即開始使用你的許可", + "WelcomePage": "歡迎頁面", + "UnsubscriptionExpireEmail": "退訂許可到期提醒郵件", + "UnsubscribeLicenseExpireEmailReminderMessage": "此電子郵件訂閱僅提醒你許可的到期日期.", + "UnsubscribeFromLicenseExpireEmails": "如果你不想收到關於許可到期郵件,你可以在任何時間取消訂閱.", + "Unsubscribe": "取消訂閱", + "NotOrganizationMember": "你不是任何組織的成員.", + "UnsubscribeLicenseExpirationEmailSuccessTitle": "退訂成功", + "UnsubscribeLicenseExpirationEmailSuccessMessage": "你不會再收到任何許可到期提醒郵件.", + "IndexPageHeroSection": "一個完整的web開發平臺基於 框架", + "AbpCommercialShortDescription": "ABP商業版提供了預構建的應用程序模塊, 快速的應用程序開發工具, 專業的UI主題, 高級支持等.", + "LiveDemo": "在線演示", + "GetLicence" :"獲得許可", + "Application": "應用程序", + "StartupTemplates": "啟動模板", + "Startup": "啟動", + "Templates": "模板", + "Developer": "開發人員", + "Tools": "工具", + "Premium": "高級", + "PremiumSupport": "高級支持", + "PremiumForumSupport": "高級論壇支持", + "UI": "UI", + "Themes": "主題", + "JoinOurNewsletter": "加入我們的時事通訊", + "Send": "發送", + "Learn": "學習", + "AdditionalServices": "額外的服務", + "WhatIsABPFramework": "什麽是ABP框架?", + "OpenSourceBaseFramework": "開源的框架", + "ABPFrameworkExplanation": "

ABP商業版基於ABP框架, 這是一個開源和社區驅動的ASP.NET Core web應用程序開發框架.

ABP框架提供了出色的基礎設施, 使用最佳實踐編寫可維護,可擴展,可測試的代碼.

基於你已經知道的流行工具. 低學習曲線,容易適應,舒適的開發體檢.

", + "Modular": "模塊化", + "MicroserviceCompatible": "微服務兼容", + "DomainDrivenDesignInfrastructure": "領域驅動設計基礎設施", + "MultiTenancy": "多租戶", + "DistributedMessaging": "分布式消息", + "DynamicProxying": "動態代理", + "BackgroundJobs": "後臺作業", + "AuditLogging": "審計日誌", + "BLOBStoring": "BLOB存儲", + "BundlingMinification": "捆綁 & 壓縮", + "AdvancedLocalization": "高級本地化", + "ManyMore": "以及更多", + "ExploreTheABPFramework": "探索ABP框架", + "WhyUseTheABPCommercial": "為什麽使用ABP商業版?", + "WhyUseTheABPCommercialExplanation": "

構建企業級的web應用程序可能復雜和耗時.

ABP商業版提供所有現代企業級基於ASP.NET Core的解決方案所需要的基礎設施. 從設計到部署,整個開發生命周期都由ABP的內置功能和模塊提供支持.

", + "StartupTemplatesShortDescription": "啟動模板使你在幾秒內快速啟動項目.", + "UIFrameworksOptions": "UI框架選項;", + "DatabaseProviderOptions": "數據庫提供程序選項;", + "PreBuiltApplicationModules": "預構建的應用程序模塊", + "PreBuiltApplicationModulesShortDescription": "大多數常見的應用程序需求已經做為可重用的模塊為你開發了.", + "Account": "賬戶", + "Blogging": "博客", + "Identity": "Identity", + "IdentityServer": "Identity Server", + "Saas": "Saas", + "LanguageManagement": "語言管理", + "TextTemplateManagement": "文本模板管理", + "See All Modules": "查看所有的模塊", + "ABPSuite": "ABP Suite", + "AbpSuiteShortDescription": "ABP Suite是ABP商業版的輔助工具.", + "AbpSuiteExplanation": "它讓你在幾分鐘內構建web頁面. 它是一個.Net Core全局工具,可以使用命令行安裝. 它可以創建一個新的ABP解決方案,從數據庫生成前端CURD頁面.", + "Details": "詳情", + "LeptonTheme": "Lepton主題", + "ProfessionalModernUIThemes": "專業, 現代化的UI主題", + "LeptonThemeExplanation": "Lepton提供了一系列的Bootstrap管理主題,為任何需要管理儀表盤的項目提供了堅實的基礎.", + "DefaultTheme": "默認主題", + "MaterialTheme": "Material主題", + "Default2Theme": "默认主題2", + "DarkTheme": "深色主題", + "DarkBlueTheme": "深藍主題", + "LightTheme": "淺色主題", + "ProudToWorkWith": "榮幸與你合作", + "OurConsumers": "全球50多個國家的數百家企業和開發商使用ABP商業版.", + "JoinOurConsumers": "加它他們並快速構建令人驚嘆的產品.", + "AdditionalServicesExplanation": "你是否需要額外或自定義的服務? 我們和我們的合作夥伴可以提供;", + "CustomProjectDevelopment": "自定義項目開發", + "CustomProjectDevelopmentExplanation": "專為你的自定義的開發人員.", + "PortingExistingProjects": "移植現有項目", + "PortingExistingProjectsExplanation": "將你的遷移傳統項目遷移到ABP平臺.", + "LiveSupport": "實時支持", + "LiveSupportExplanation": "在你需要時,可以實時提供遠程支持選項.", + "Training": "培訓", + "TrainingExplanation": "為你的開發人員提供專門培訓.", + "OnBoarding": "管理", + "OnBoardingExplanation": "幫助設置你的開發,CI和CD環境.", + "PrioritizedTechnicalSupport": "優先的技術支持", + "PremiumSupportExplanation": "除了社區對ABP框架出色支持外,我們的支持團隊會優先回答商業用戶的技術問題.", + "SeeTheSupportOptions": "查看支持選項", + "Contact": "聯系", + "TellUsWhatYouNeed": "告訴我們你需要什麽.", + "YourMessage": "你的消息", + "YourFullName": "你的全名", + "EmailField": "E-mail地址", + "YourEmailAddress": "你的e-mail地址", + "HowMayWeHelpYou": "我們如何幫助你", + "SendMessage": "發送消息", + "Success": "成功", + "WeWillReplyYou": "你的消息已經發送! 我們會在短時間內給你答復.", + "GoHome": "回到主頁面", + "CreateLiveDemo": "創建在線演示", + "RegisterToTheNewsletter": "註冊到時事簡報以獲取有關ABP.IO的消息,比如新發布的內容.", + "EnterYourEmailOrLogin": "輸入你的e-mail地址來創建你的演示或者使用你的已有賬號登錄.", + "ApplicationTemplate": "應用程序模板", + "ApplicationTemplateExplanation": "應用程序啟動模板用於創建新的web應用程序.", + "EfCoreProvider": "Entity Framework (支持 SQL Server, MySQL, PostgreSQL, Oracle 和其它)", + "AlreadyIncludedInTemplateModules": "以下模塊已經包含並配置在此模板中:", + "ApplicationTemplateArchitecture": "應用程序模板還支持UI,API,身份驗證服務器物理分離的分層架構.", + "SeeTheGuideOrGoToTheLiveDemo": "查看開發人員指南或者查看在線演示了解更多關於模板的信息.", + "DeveloperGuide": "開發人員指南", + "ModuleTemplate": "模块模板", + "ModuleTemplateExplanation1": "你是否想要創建可在不同應用程序之間重用的模塊? 這個啟動模板準備好了一切來創建可重用的應用程序模塊或微服務.", + "ModuleTemplateExplanation2": "

你可以為一個模塊支持單個或多個UI框架, 單個或多個數據庫提供程序. 除了單元測試和集成測試基礎架構外,啟動模板被配置為在一個最小的應用程序中運行和測試你的模塊.

查看開發人員指南了解有關此模板的技術信息.

", + "WithAllStyleOptions": "使用所有的樣式選項", + "Demo": "演示", + "SeeAllModules": "查看所有的模塊", + "ABPCLIExplanation": "ABP CLI(命令行頁面)是一個執行基於ABP解決方案的一些常見操作的命令行工具.", + "ABPSuiteEasilyCURD": "ABP Suite是一個使你輕松創建CURD頁面的工具", + "WeAreHereToHelp": "我們在這裏為你提供幫助", + "BrowseOrAskQuestion": "你可以瀏覽我們的幫助主題或搜索常見的問題, 或者你可以使用聯系表單向我們提問.", + "SearchQuestionPlaceholder": "搜索常見的問題", + "WhatIsTheABPCommercial": "什麽是ABP商業版?", + "WhatAreDifferencesThanAbpFramework": "ABP框架與ABP商業版有什麽不同?", + "ABPCommercialExplanation": "ABP商業版是一套基於開源ABP框架之上的高級模塊,工具,主題和服務. ABP商業版由ABP框架背後的同一團隊開發和支持.", + "WhatAreDifferencesThanABPFrameworkExplanation": "

ABP框架是模塊化,主題化,微服務兼容的ASP.NET Core應用程序開發框架. 它提供了一個完整的架構和強大的基礎設施,讓你專註於自己的業務代碼而不是重復自己的每一個項目. 它基於軟件開發的最佳實踐和你已經知道的流行工具

ABP框架是完全免費,開源和由社區驅動的. 它還提供了一個免費的主題和一些預構建的模塊 (如 identity管理和租戶管理).

", + "VisitTheFrameworkVSCommercialDocument": "訪問以下鏈接,了解更多信息 {1} ", + "ABPCommercialFollowingBenefits": "ABP商業版在ABP框架之上添加了以下好處;", + "Professional": "專業的", + "UIThemes": "UI主題", + "EnterpriseModules": "企業就緒,功能豐富,預構建的應用程序模塊 (如 Identity Server管理, SaaS管理, 語言管理)", + "ToolingToSupport": "支持你的生產力的工具(如. ABP Suite)", + "PremiumSupportLink": "高級支持", + "WhatDoIDownloadABPCommercial": "購買ABP商業版後我可以下載什麽?", + "CreateUnlimitedSolutions": "一旦你購買了ABP商業許可, 你可以創建入門文檔中描述的無限的解決方案.", + "ABPCommercialSolutionExplanation": "創建新應用程序時,將根據你的首選項獲得Visual Studio解決方案(啟動模板). 下載的解決方案已為你安裝並配置了商業模塊和主題. 你可以刪除預裝的模塊,也可以根據需要添加其他模塊. 默認情況下所有模塊和主題都使用NuGet/NPM軟件包.", + "StartDevelopWithTutorials": "下載的解決方案經過精心設計和記錄, 你可以根據教程來開發自己的業務代碼.", + "TryTheCommercialDemo": "你可以嘗試示例來查看使用ABP商業模板創建的示例應用程序.", + "HowManyProducts": "使用ABP商業版,我可以構建多少不同的產品/解決方案?", + "HowManyProductsExplanation": "創建ABP項目沒有限制. 你可以根據需要創建任意數量的項目,進行開發並將其部署到其他服務器.", + "HowManyDevelopers": "有多少開發者可以參與ABP商業版工作?", + "HowManyDevelopersExplanation": "ABP商業許可是針對每個開發人員的. 不同的許可類型具有不同的開發人員限制. 但是你可以在需要時將更多開發人員添加到任何許可類型. 查看許可類型,開發人員限制和額外的開發人員成本的價格頁面.", + "ChangingLicenseType": "將來更改我的許可類型嗎?", + "ChangingLicenseTypeExplanation": "你始終可以在同一許可中添加新的開發人員. 參閱 \"有多少開發者可以參與ABP商業版工作?\". 你還可以通過支付計算出的價格差來升級到更高的許可. 當你升級到更高的許可計劃時,可以享受新計劃的好處,但是許可升級不會更改許可的到期日期.", + "LicenseExtendUpgradeDiff": "許可擴展和升級有什麽區別?", + "LicenseExtendUpgradeDiffExplanation": "擴展: 通過擴展/更新許可,你將繼續獲得高級支持,並獲得有關模塊和主題的重大更新. 此外你將能夠繼續創建新項目. 而且你仍然可以使用ABP Suite來加快開發速度.
升級: 通過升級許可,你將升級到更高的許可計劃,這將使你獲得更多好處. 查看 許可比較表來檢查許可計劃之間的差異. 另一方面,當你升級時你的許可到期日期不會改變!要延長你的許可終止日期,你需要延長你的許可.", + "LicenseRenewalCost": "一年後的許可續期費用是多少?", + "LicenseRenewalCostExplanation": "ABP商業版的續費價格均為原價的{0}. Team版本的續費價格是${1}, Business版本的續訂價格是${2}, Enterprise版本的續訂價格是${3}. 如果你已經購買了, 請登錄帳戶以查看續訂價格.", + "HowDoIRenewMyLicense": "如何續費我的許可證?", + "HowDoIRenewMyLicenseExplanation": "你可以登錄以進行續費. 為了享受我們的續費折扣, 請確保在許可證到期之前進行續費, 我們會在到期前7天和30天發送2封續費提醒郵件.", + "IsSourceCodeIncluded": "我的許可是否包括商業模塊和主題的源代碼?", + "IsSourceCodeIncludedExplanation1": "取決於你購買的許可類型:", + "IsSourceCodeIncludedExplanation2": "團隊: 你的解決方案將這些模塊和主題作為NuGet和NPM包使用. 它不包括其源代碼. 這樣,只要有新版本可用,你就可以輕松升級這些模塊和主題. 但是,你無法獲取模塊和主題的源代碼.", + "IsSourceCodeIncludedExplanation3": "商業/企業: 除了團隊許可外,你還可以下載所需的任何模塊或主題的源代碼. 你甚至可以刪除特定模塊的NuGet/NPM軟件包引用,並將其源代碼直接添加到你的解決方案中以完全更改它.", + "IsSourceCodeIncludedExplanation4": "

將模塊的源代碼包含到解決方案中,可以最大程度地自定義該模塊. 但是當新版本發布時,將無法自動升級模塊.

這些許可均不包含ABP Suite源代碼,該源代碼是一個外部工具,可以為你生成代碼並幫助你進行開發

有關許可類型之間的其它差異查看定價頁面.

", + "ChangingDevelopers": "我將來可以更改我組織的註冊開發人員嗎?", + "ChangingDevelopersExplanation": "除了將新的開發人員添加到你的許可中之外,你還可以更改現有的開發人員(可以刪除一個開發人員並將新的開發人員添加到同一位置),而無需任何額外費用.", + "WhatHappensWhenLicenseEnds": "我的許可期限結束後會怎樣?", + "WhatHappensWhenLicenseEndsExplanation1": "ABP商業版具有永久許可類型.許可到期後, 你可以繼續開發你的項目.並且你沒有義務續訂許可.許可到期後;", + "WhatHappensWhenLicenseEndsExplanation2": "你不能使用ABP商業版創建新的解決方案,但可以永遠繼續開發現有的應用程序.", + "WhatHappensWhenLicenseEndsExplanation3": "你能夠在你的主版本中獲得模塊和主題的更新.例如;如果你使用的是模塊的v3.2.0版本,你仍然可以獲得v3.x.x版本的更新.(v3.3.0 v3.5.2…等等)的.但是你無法獲得下一個主要版本(如v4.x,v5.x)的更新", + "WhatHappensWhenLicenseEndsExplanation4": "許可到期後,你無法安裝添加到ABP商業平臺的新模塊和主題.", + "WhatHappensWhenLicenseEndsExplanation5": "你不能使用ABP Suite.", + "WhatHappensWhenLicenseEndsExplanation6": "你不再獲得高級支持.", + "WhatHappensWhenLicenseEndsExplanation7": "如果你想繼續獲得這些好處,可以繼續續訂. 續訂時有20%的折扣.", + "WhenShouldIRenewMyLicense": "我什麽時候應該續訂我的許可?", + "WhenShouldIRenewMyLicenseExplanation1": "如果你在许可到期后的 1个月内续订许可,则许可总价将享受%20的折扣.", + "WhenShouldIRenewMyLicenseExplanation2": "如果你在你的許可過期日期1個月後更新你的許可,更新價格將與許可購買價格相同,你的更新將沒有折扣.", + "TrialPlan": "你們有試用計劃嗎?", + "TrialPlanExplanation": "目前,ABP商業版還沒有試用計劃.對於團隊許可,我們提供30天的退款保證.你可以在30天內要求退款.對於企業營業執照,我們提供30天內60%的退款.這是因為商業和企業許可包含所有模塊和主題的完整源代碼.", + "DoYouAcceptBankWireTransfer": "你們接受銀行電匯嗎?", + "DoYouAcceptBankWireTransferExplanation": "是的,我們接受銀行電匯.
通過銀行電匯轉賬,通過電子郵件將收據和所要求的許可類型發送給我們.
我們的國際銀行帳戶信息:", + "HowToUpgrade": "可用新版本時如何升級現有應用程序?", + "HowToUpgradeExplanation1": "使用ABP商業版創建新應用程序時,所有模塊和主題均用作NuGet和NPM軟件包. 因此,當有新版本可用時,你可以輕松升級軟件包.", + "HowToUpgradeExplanation2": "除了標準的NuGet/NPM升級之外, ABP CLI 還提供了一條更新命令,該命令可自動查找和升級解決方案中的所有與ABP相關的軟件包.", + "DatabaseSupport": "支持哪些數據庫系統?", + "DatabaseSupportExplanation": "ABP框架本身與數據庫無關,並且就其性質而言,可以與任何數據庫提供程序一起使用. 請參閱數據訪問文檔以獲取當前實現的提供程序的列表.", + "UISupport": "支持哪些UI框架?", + "Supported": "支持的", + "UISupportExplanation": "ABP框架本身與UI框架無關,並且可以與任何UI框架一起使用. 但是,並非針對所有UI框架都實現了啟動模板,模塊UI和主題. 有關UI選項的最新列表,請參見入門文檔.", + "MicroserviceSupport": "它是否支持微服務架構?", + "MicroserviceSupportExplanation1": "ABP框架的主要目標之一是為創建微服務解決方案提供便利的基礎架構. 請參閱微服務體系結構文檔,以了解它如何幫助創建微服務系統.", + "MicroserviceSupportExplanation2": "所有的ABP商業模塊通過模塊開發最佳實踐文檔被設計為支持微服務部署場景(使用自己的API和數據庫).", + "MicroserviceSupportExplanation3": "我們提供了一個示例微服務演示解決方案,該示例演示了一種微服務架構實現,可幫助你創建自己的解決方案.", + "MicroserviceSupportExplanation4": "所以簡短的答案是 \"是的, 它支持微服務體系結構\".", + "MicroserviceSupportExplanation5": "但是,微服務系統是一個解決方案,每個解決方案都有不同的要求,網絡拓撲,通信場景,身份驗證可能性,數據庫分離/共享決策,運行時配置,第三方系統集成等等.", + "MicroserviceSupportExplanation6": "ABP框架和ABP商業版提供了微服務方案,微服務兼容模塊,示例和文檔的基礎結構,以幫助你構建自己的解決方案. 但是不要期望直接下載為你預先構建的夢想解決方案. 你將需要了解它,並根據需要將某些部分組合在一起.", + "WhereCanIDownloadSourceCode": "在哪裏可以下載源代碼?", + "WhereCanIDownloadSourceCodeExplanation": "你可以通過ABP Suite或ABP CLI下載所有ABP模塊,Angular軟件包和主題的源代碼. 請參見如何下載源代碼?", + "ComputerLimitation": "開發人員在開發ABP時可以登錄到多少臺計算機?", + "ComputerLimitationExplanation": "我們特別允許每個個人/許可的開發人員使用 {0}臺計算機. 每當需要開發人員在第三臺計算機上開發ABP商業產品時,都應將電子郵件發送到license@abp.io,以說明情況,然後我們將在系統中進行適當分配.", + "RefundPolicy": "你們有退款政策嗎?", + "RefundPolicyExplanation": "你可以在購買許可的30天內請求退款.商業和企業許可類型都有源代碼下載選項,因此商業和企業(以及任何包含獲得源代碼的權利的許可)都不能退款.此外,續展和購買第二次許可也不退款.", + "HowCanIRefundVat": "我該如何退還增值稅?", + "HowCanIRefundVatExplanation1": "如果你使用2Checkout付款,則可以通過2Checkout帳戶退還增值稅:", + "HowCanIRefundVatExplanation2": "登錄到你的2Checkout賬戶", + "HowCanIRefundVatExplanation3": "找到適當的訂單,然後按\"退還已延期的增值稅\"(輸入你的增值稅ID", + "HowCanIGetMyInvoice": "我如何獲得發票?", + "HowCanIGetMyInvoiceExplanation": "有兩個用於購買許可的支付網關:PayU和2Checkout. 如果你通過2Checkout網關購買許可,則它將PDF發票發送到你的電子郵件地址,請參閱2Checkout發票.如果你是通過PayU網關或通過銀行電匯購買的,我們將準備並發送你的發票. 你可以從組織管理頁面索取發票.", + "Forum": "論壇", + "SupportExplanation": "ABP商業版許可包含由ABP框架專家組成的團隊提供的高級論壇支持.", + "PrivateTicket": "私有票", + "PrivateTicketExplanation": "企業許可還包含帶有電子郵件和票系統的私人支持.", + "AbpSuiteExplanation1": "ABP Suite使你在幾分鐘內構建web頁面. 它是一個.NET Core Global工具,可以使用命令行安裝.", + "AbpSuiteExplanation2": "它可以創建一個新的ABP解決方案, 從數據庫生成前端CURD頁面. 有關技術概述查看文檔", + "FastEasy": "快速並且簡單", + "AbpSuiteExplanation3": "ABP Suite允許你輕松的創建CURD頁面. 你只需要定義你的實體和它的屬性, 其它的讓ABP Suite幫你完成! ABP Suite會在幾秒內為你生成CURD頁面和必要的代碼. 它支持Angular, MVC和 Blazor用戶界面.", + "RichOptions": "豐富的選項", + "AbpSuiteExplanation4": "ABP Suite支持多個UI選項,例如 Razor Pages和Angular.它還支持多個數據庫, 如 MongoDB 和EntityFramework Core支持的所有數據庫(MS SQL Server, Oracle, MySql, PostgreSQL 和 更多).", + "AbpSuiteExplanation5": "好消息是, 你不必擔心這些選項. ABP Suite了解你的項目類型並且將生成的代碼放到項目中正確的位置.", + "SourceCode": "源碼", + "AbpSuiteExplanation6": "ABP Suite為你生成源代碼! 它不會生成魔法文件來生成web頁面. ABP Suite為實體, 倉儲, 應用程序, Code First遷移, JavaScript/TypeScript 和 CSHTML/HTML以及必要的頁面生成源代碼. ABP Suite根據軟件開發的最佳實踐來生成代碼, 所以你不必擔心生成的代碼的質量.", + "AbpSuiteExplanation7": "由於你有應用程序層中生成的CURD頁面的構建塊的源代碼, 因此你可以輕松修改源碼並將自定義/業務邏輯註入到所生成的代碼中.", + "CrossPlatform": "跨平台", + "AbpSuiteExplanation8": "ABP Suite使用.NET Core構建並且它是跨平臺的. 它在你的本地電腦中運行為web應用程序. 你可以在Windows, Mac和Linux上運行它", + "OtherFeatures": "其他功能", + "OtherFeatures1": "輕松更新你的解決方案的NuGet和NPM包.", + "OtherFeatures2": "重新生成已經生成的頁面.", + "OtherFeatures3": "創建新的解決方案", + "ThanksForCreatingProject": "感謝你創建你的項目!", + "HotToRunSolution": "如何運行你的解決方案?", + "HotToRunSolutionExplanation": "查看入門文檔來學習如何配置和運行你的解決方案.", + "GettingStarted": "入門", + "WebAppDevTutorial": "Web應用開發教程", + "WebAppDevTutorialExplanation": "查看web應用程序開發教程文檔來一步一步的了解開發示例.", + "Document": "文檔", + "UsingABPSuiteToCURD": "使用ABP Suite來生成CURD頁面", + "SeeABPSuiteDocument": "查看ABP Suite文檔學習如何使用ABP Suite.", + "AskQuestionsOnSupport": "你可以在ABP商業支持提出問題.", + "Documentation": "文檔", + "SeeModulesDocument": "查看模塊文檔獲取所有商業(專業)模塊列表和它們的文檔.", + "Pricing": "價格", + "PricingExplanation": "選擇當前業務需要的特性和功能. 隨著業務增長輕松升級.", + "Team": "團隊", + "Business": "商業", + "Enterprise": "企業", + "Custom": "自定義", + "IncludedDeveloperLicenses": "包括開發人員許可", + "CustomLicenceOrAdditionalServices": "需要自定義許可與額外服務?", + "CustomOrVolumeLicense": "自定義或批量許可", + "LiveTrainingSupport": "現場培訓和支持", + "AndMore": "和更多", + "AdditionalDeveloperLicense": "額外的開發人員許可", + "ProjectCount": "項目數量", + "AllProModules": "所有模塊", + "AllProThemes": "所有主題", + "AllProStartupTemplates": "所有專業啟動模板", + "SourceCodeOfAllModules": "所有模塊的源碼", + "SourceCodeOfAllThemes": "所有主題的源碼", + "PerpetualLicense": "永久的許可", + "UnlimitedServerDeployment": "無限制的服務器部署", + "YearUpgrade": "1年升級", + "YearPremiumForumSupport": "1年高級論壇支持", + "ForumSupportIncidentCountYear": "論壇支持事件數量/年", + "PrivateTicketEmailSupport": "私有票和email支持", + "BuyNow": "現在購買", + "PayViaAmexCard": "我如何通過我的AMEX卡付款?", + "PayViaAmexCardDescription": "由於安全措施,默認付款網關'Iyzico'可能會拒絕某些AMEX信用卡. 在這種情況下,完全可以通過備用付款網關'2Checkout'付款.", + "InvalidReCaptchaErrorMessage": "验证reCAPTCHA时出错,请重试.", + "CompanyName": "公司名稱", + "YourCompanyName": "你的公司名稱", + "FirstName": "名", + "LastName": "姓", + "Optional": "可選的", + "YourFirstName": "你的名字", + "YourLastName": "你的姓氏", + "SpecialOffer": "特別優惠", + "SpecialOfferMessage": "盡快付款,價格在一定時間內有效.", + "DiscountRequest": "折扣申請", + "DiscountRequestDescribeCustomerQuestion": "以下哪個選項描述了你?", + "DiscountRequestStudentEmailMessage": "Email地址必須包含'edu'.", + "DiscountRequestDeveloperCount": "你有多少開發人員?", + "DiscountRequestDeveloperCountExceedMessage": "對於超過 {0} 開發人員的公司,我們不提供折扣.", + "DiscountRequestOrganizationName": "公司/組織/學校名稱", + "Website": "網站", + "GithubUsername": "GitHub用戶名", + "PhoneNumber": "手機號", + "Country": "國家", + "DescribeABPCommercialUsage": "描述你基於ABP商業版進行開發的項目", + "DiscountRequestCertifyInformationMessage": "我證明所有的信息都是真實的.", + "DiscountRequestReceived": "我們收到了你的折扣請求.", + "DiscountRequestStatusMessage": "我們會檢查你提供的信息並且給你答復.", + "MVCOrRazorPages": "MVC (Razor Pages)", + "Angular": "Angular", + "Blazor": "Blazor", + "New": "新的", + "MongoDB": "MongoDB" + } } \ No newline at end of file diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/FR.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/fr.json similarity index 99% rename from abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/FR.json rename to abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/fr.json index 8c382f760e..734dadadcd 100644 --- a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/FR.json +++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/fr.json @@ -51,7 +51,7 @@ "Answer": "Répondre", "Views": "vues", "Answered": "Répondu", - "WaitingForYourAnswer": "J'attends ta réponse", + "WaitingForYourAnswer": "En attente de votre réponse", "Asked": "demandé", "AllQuestions": "Toutes les questions", "NextVersion": "Version suivante", diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/hi.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/hi.json new file mode 100644 index 0000000000..a3f824d6ba --- /dev/null +++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/hi.json @@ -0,0 +1,147 @@ +{ + "culture": "hi", + "texts": { + "Permission:CommunityArticle": "सामुदायिक अनुच्छेद", + "Permission:Edit": "संपादित करें", + "Waiting": "इंतज़ार कर रही", + "Approved": "मंजूर की", + "Rejected": "अस्वीकृत", + "Wait": "रुको", + "Approve": "मंजूर", + "Reject": "अस्वीकार", + "ReadArticle": "लेख पढ़ें", + "Status": "स्थिति", + "ContentSource": "विषय - वस्तु का स्रोत", + "Details": "विवरण", + "Url": "यूआरएल", + "Title": "शीर्षक", + "CreationTime": "रचना समय", + "Save": "सहेजें", + "SameUrlAlreadyExist": "वही url पहले से मौजूद है यदि आप इस लेख को जोड़ना चाहते हैं, तो आपको url को बदल देना चाहिए!", + "UrlIsNotValid": "यू आर एल मान्य नहीं है।", + "UrlNotFound": "Url नहीं मिला।", + "UrlContentNotFound": "यूआरएल सामग्री नहीं मिली।", + "Summary": "सारांश", + "MostRead": "सबसे ज़्यादा पढ़ा हुआ", + "Latest": "नवीनतम", + "ContributeAbpCommunity": "ABP समुदाय में योगदान दें", + "SubmitYourArticle": "अपनी पोस्ट सबमिट करें", + "ContributionGuide": "योगदान गाइड", + "BugReport": "बग रिपोर्ट", + "SeeAllArticles": "सभी पोस्ट देखें", + "WelcomeToABPCommunity!": "ABP समुदाय में आपका स्वागत है!", + "MyProfile": "मेरी प्रोफाइल", + "MyOrganizations": "मेरे संगठन", + "EmailNotValid": "कृपया एक वैध ई - मेल एड्रेस डालें।", + "FeatureRequest": "महत्वपूर्ण लेख मांगना", + "CreateArticleTitleInfo": "पोस्ट का शीर्षक पोस्ट सूची पर दिखाया जाना है।", + "CreateArticleSummaryInfo": "पोस्ट सूची पर दिखाए जाने वाले पोस्ट का संक्षिप्त सारांश।", + "CreateArticleCoverInfo": "एक प्रभावी लेख बनाने के लिए, एक कवर फ़ोटो जोड़ें। सर्वश्रेष्ठ दृश्य के लिए 16: 9 पहलू अनुपात चित्र अपलोड करें। अधिकतम फ़ाइल आकार: 1 एमबी।", + "ThisExtensionIsNotAllowed": "इस एक्सटेंशन की अनुमति नहीं है।", + "TheFileIsTooLarge": "फ़ाइल बहुत बड़ी है।", + "GoToTheArticle": "लेख पर जाएं", + "Contribute": "योगदान", + "OverallProgress": "समग्र प्रगति", + "Done": "किया हुआ", + "Open": "खुला हुआ", + "Closed": "बंद किया हुआ", + "LatestQuestionOnThe": "पर नवीनतम प्रश्न", + "Stackoverflow": "स्टैक ओवरफ़्लो", + "Votes": "वोट", + "Answer": "उत्तर", + "Views": "विचारों", + "Answered": "उत्तर", + "WaitingForYourAnswer": "आपके जवाब का इंतज़ार", + "Asked": "पूछा", + "AllQuestions": "सभी प्रश्न", + "NextVersion": "अगला संस्करण", + "MilestoneErrorMessage": "Github से वर्तमान मील का पत्थर का विवरण नहीं मिल सका।", + "QuestionItemErrorMessage": "Stackoverflow से नवीनतम प्रश्न विवरण प्राप्त नहीं कर सका।", + "Oops": "उफ़!", + "CreateArticleSuccessMessage": "अनुच्छेद सफलतापूर्वक प्रस्तुत किया गया है। इसे साइट व्यवस्थापक से समीक्षा के बाद प्रकाशित किया जाएगा।", + "ChooseCoverImage": "कवर छवि चुनें ...", + "CoverImage": "कवर छवि", + "ShareYourExperiencesWithTheABPFramework": "ABP फ्रेमवर्क के साथ अपने अनुभव साझा करें!", + "Optional": "ऐच्छिक", + "UpdateUserWebSiteInfo": "उदाहरण: https://johndoe.com", + "UpdateUserTwitterInfo": "उदाहरण: जॉन्डो", + "UpdateUserGithubInfo": "उदाहरण: जॉन्डो", + "UpdateUserLinkedinInfo": "उदाहरण: https: //www.linkedin.com / ...", + "UpdateUserCompanyInfo": "उदाहरण: वोलोसॉफ्ट", + "UpdateUserJobTitleInfo": "उदाहरण: सॉफ्टवेयर डेवलपर", + "UserName": "उपयोगकर्ता नाम", + "Company": "कंपनी", + "PersonalWebsite": "व्यक्तिगत वेबसाइट", + "RegistrationDate": "पंजीकरण की तारीख", + "Social": "सामाजिक", + "Biography": "जीवनी", + "HasNoPublishedArticlesYet": "अभी तक कोई प्रकाशित लेख नहीं है", + "Author": "लेखक", + "LatestGithubAnnouncements": "नवीनतम गितूब घोषणाएँ", + "SeeAllAnnouncements": "सभी घोषणाएँ देखें", + "LatestBlogPost": "नवीनतम ब्लॉग पोस्ट", + "Edit": "संपादित करें", + "ProfileImageChange": "प्रोफ़ाइल छवि बदलें", + "BlogItemErrorMessage": "ABP से नवीनतम ब्लॉग पोस्ट विवरण नहीं मिल सका।", + "PlannedReleaseDate": "योजना जारी करने की तारीख", + "CommunityArticleRequestErrorMessage": "जीथब से नवीनतम लेख अनुरोध नहीं मिल सका।", + "ArticleRequestFromGithubIssue": "अब कोई लेख अनुरोध नहीं है।", + "LatestArticles": "नवीनतम पोस्ट", + "ArticleRequests": "लेख अनुरोध", + "AllArticleRequests": "सभी लेख अनुरोध देखें", + "SubscribeToTheNewsletter": "न्यूज़लेटर की सदस्यता लें", + "NewsletterEmailDefinition": "एबीपी में होने वाली घटनाओं के बारे में जानकारी प्राप्त करें जैसे नए रिलीज़, मुफ्त स्रोत, लेख, और बहुत कुछ।", + "NoThanks": "जी नहीं, धन्यवाद", + "MaybeLater": "शायद बाद में", + "JoinOurArticleNewsletter": "हमारे लेख समाचार पत्र में शामिल हों", + "Community": "समुदाय", + "Marketing": "विपणन", + "CommunityPrivacyPolicyConfirmation": "मैं नियम और शर्तों और गोपनीयता नीति से सहमत हूं।", + "ArticleRequestMessageTitle": "GitHub पर एक लेख / ट्यूटोरियल जिसे आप इस वेब साइट पर देखना चाहते हैं, का अनुरोध करने के लिए एक समस्या खोलें ।", + "ArticleRequestMessageBody": "यहाँ, समुदाय द्वारा अनुरोधित लेखों की सूची। क्या आप एक अनुरोधित लेख लिखना चाहते हैं? कृपया अनुरोध पर क्लिक करें और चर्चा में शामिल हों।", + "Language": "भाषा: हिन्दी", + "CreateArticleLanguageInfo": "पोस्ट सामग्री के लिए भाषा।", + "VideoPost": "वीडियो पोस्ट", + "Article": "लेख", + "Read": "पढ़ें", + "CreateGithubArticleUrlInfo": "मूल GitHub लेख का URL।", + "CreateVideoContentUrlInfo": "पोस्ट का मूल Youtube URL।", + "CreateExternalArticleUrlInfo": "लेख के मूल बाहरी यूआरएल।", + "VideoContentForm": "YouTube पर वीडियो सबमिट करें", + "GithubPostForm": "GitHub पर लेख प्रस्तुत करें", + "ExternalPostForm": "एक बाहरी सामग्री सबमिट करें", + "HowToPost": "पोस्ट कैसे करें?", + "Posts": "पदों", + "VideoUrl": "वीडियो यूआरएल", + "GithubArticleUrl": "गीथब लेख उराल", + "ExternalArticleUrl": "बाहरी लेख यूआरएल", + "CreatePostCoverInfo": "एक प्रभावी पोस्ट बनाने के लिए, एक कवर फ़ोटो जोड़ें। सर्वश्रेष्ठ दृश्य के लिए 16: 9 पहलू अनुपात चित्र अपलोड करें। अधिकतम फ़ाइल आकार: 1 एमबी।", + "ThankYouForContribution": "ABP समुदाय में योगदान के लिए धन्यवाद।", + "GithubArticle": "गीथब लेख", + "GithubArticleSubmitStepOne": " 1। मार्कडाउन प्रारूप के साथ किसी भी सार्वजनिक GitHub रिपॉजिटरी पर एक लेख लिखें। उदाहरण ", + "GithubArticleSubmitStepTwo": " 2। फ़ॉर्म का उपयोग करके अपना लेख URL सबमिट करें।", + "GithubArticleSubmitStepThree": " 3। इस वेब साइट में आपका लेख प्रस्तुत किया जाएगा।", + "YoutubeVideo": "यूट्यूब वीडियो", + "YoutubeVideoSubmitStepOne": " 1। YouTube पर अपना वीडियो प्रकाशित करें।", + "YoutubeVideoSubmitStepTwo": " 2। फ़ॉर्म का उपयोग करके वीडियो URL सबमिट करें।", + "YoutubeVideoSubmitStepThree": " 3। आगंतुक इस वेबसाइट पर सीधे आपकी वीडियो सामग्री देख सकेंगे।", + "ExternalContent": "बाहरी सामग्री", + "ExternalContentSubmitStepOne": " 1। किसी भी सार्वजनिक मंच पर एक सामग्री बनाएं (मध्यम, अपना स्वयं का ब्लॉग या कहीं भी आप चाहें)।", + "ExternalContentSubmitStepTwo": " 2। फ़ॉर्म का उपयोग करके अपना सामग्री URL सबमिट करें।", + "ExternalContentSubmitStepThree": " 3। मूल वेबसाइट पर आगंतुकों को सामग्री पर पुनर्निर्देशित किया गया है।", + "ChooseYourContentType": "कृपया अपनी सामग्री जोड़ने का तरीका चुनें।", + "PostContentViaGithub": "मैं अपना लेख जोड़ना चाहता हूं GitHub अंकन नियमों के अनुसार।", + "PostContentViaYoutube": "मैं यहां उपलब्ध अपने वीडियो को Youtube पर साझा करना चाहता हूं।", + "PostContentViaExternalSource": "मैं यहां एक अन्य प्लेटफ़ॉर्म पर प्रकाशित सामग्री जोड़ना चाहता हूं।", + "GitHubUserNameValidationMessage": "आपके Github उपयोगकर्ता नाम में व्हॉट्सएप शामिल नहीं हो सकता है, कृपया सुनिश्चित करें कि आपका Github उपयोगकर्ता नाम सही है।", + "PersonalSiteUrlValidationMessage": "आपके व्यक्तिगत साइट URL में व्हॉट्सएप शामिल नहीं हो सकता है, कृपया सुनिश्चित करें कि आपका व्यक्तिगत साइट URL सही है।", + "TwitterUserNameValidationMessage": "आपके ट्विटर उपयोगकर्ता नाम में व्हाट्सएप शामिल नहीं हो सकता है, कृपया सुनिश्चित करें कि आपका ट्विटर उपयोगकर्ता नाम सही है।", + "LinkedinUrlValidationMessage": "आपके लिंक्डइन URL में व्हॉट्सएप शामिल नहीं हो सकता है, कृपया सुनिश्चित करें कि आपका लिंक्डइन URL सही है।", + "NoPostsFound": "कोई प्रकाशन नहीं मिला!", + "SearchInPosts": "पदों में खोजें ...", + "MinimumSearchContent": "आपको कम से कम 3 वर्ण दर्ज करने होंगे!", + "Volo.AbpIo.Domain:060001": "स्रोत URL (\"{ArticleUrl}\") जीथब URL नहीं है", + "Volo.AbpIo.Domain:060002": "लेख सामग्री Github (\"{ArticleUrl}\") संसाधन से उपलब्ध नहीं है।", + "Volo.AbpIo.Domain:060003": "कोई लेख सामग्री नहीं मिली!" + } +} \ No newline at end of file diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/it.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/it.json new file mode 100644 index 0000000000..6e8dfc31e7 --- /dev/null +++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/it.json @@ -0,0 +1,147 @@ +{ + "culture": "it", + "texts": { + "Permission:CommunityArticle": "Articolo comunitario", + "Permission:Edit": "modificare", + "Waiting": "In attesa", + "Approved": "Approvato", + "Rejected": "Respinto", + "Wait": "Aspettare", + "Approve": "Approvare", + "Reject": "Rifiutare", + "ReadArticle": "Leggi l'articolo", + "Status": "Stato", + "ContentSource": "Fonte di contenuto", + "Details": "Dettagli", + "Url": "Url", + "Title": "Titolo", + "CreationTime": "Tempo di creazione", + "Save": "Salva", + "SameUrlAlreadyExist": "Lo stesso URL esiste già se vuoi aggiungere questo articolo, dovresti cambiare l'URL!", + "UrlIsNotValid": "URL non valido.", + "UrlNotFound": "URL non trovato.", + "UrlContentNotFound": "Contenuto URL non trovato.", + "Summary": "Sommario", + "MostRead": "I più letti", + "Latest": "Ultimo", + "ContributeAbpCommunity": "Contribuisci alla comunità ABP", + "SubmitYourArticle": "Invia il tuo post", + "ContributionGuide": "Guida al contributo", + "BugReport": "Riportare un errore", + "SeeAllArticles": "Vedi tutti i post", + "WelcomeToABPCommunity!": "Benvenuto nella comunità ABP!", + "MyProfile": "Il mio profilo", + "MyOrganizations": "Le mie organizzazioni", + "EmailNotValid": "Si prega di inserire un indirizzo email valido.", + "FeatureRequest": "Richiesta di funzionalità", + "CreateArticleTitleInfo": "Titolo del post da mostrare nell'elenco dei post.", + "CreateArticleSummaryInfo": "Un breve riassunto del post da mostrare nell'elenco dei post.", + "CreateArticleCoverInfo": "Per creare un articolo efficace, aggiungi una foto di copertina. Carica immagini in formato 16: 9 per una visualizzazione migliore. Dimensione massima del file: 1 MB.", + "ThisExtensionIsNotAllowed": "Questa estensione non è consentita.", + "TheFileIsTooLarge": "Il file è troppo grande.", + "GoToTheArticle": "Vai all'articolo", + "Contribute": "Contribuire", + "OverallProgress": "Progressi generali", + "Done": "Fatto", + "Open": "Aperto", + "Closed": "Chiuso", + "LatestQuestionOnThe": "Ultima domanda su", + "Stackoverflow": "Stackoverflow", + "Votes": "voti", + "Answer": "Risposta", + "Views": "visualizzazioni", + "Answered": "Risposto", + "WaitingForYourAnswer": "In attesa della tua risposta", + "Asked": "chiesto", + "AllQuestions": "Tutte le domande", + "NextVersion": "Versione successiva", + "MilestoneErrorMessage": "Impossibile ottenere i dettagli della pietra miliare corrente da Github.", + "QuestionItemErrorMessage": "Impossibile ottenere gli ultimi dettagli della domanda da Stackoverflow.", + "Oops": "Ops!", + "CreateArticleSuccessMessage": "L'articolo è stato inviato con successo. Verrà pubblicato dopo una revisione da parte dell'amministratore del sito.", + "ChooseCoverImage": "Scegli un'immagine di copertina ...", + "CoverImage": "Immagine di copertina", + "ShareYourExperiencesWithTheABPFramework": "Condividi le tue esperienze con ABP Framework!", + "Optional": "Opzionale", + "UpdateUserWebSiteInfo": "Esempio: https://johndoe.com", + "UpdateUserTwitterInfo": "Esempio: johndoe", + "UpdateUserGithubInfo": "Esempio: johndoe", + "UpdateUserLinkedinInfo": "Esempio: https: //www.linkedin.com / ...", + "UpdateUserCompanyInfo": "Esempio: Volosoft", + "UpdateUserJobTitleInfo": "Esempio: sviluppatore di software", + "UserName": "Nome utente", + "Company": "Azienda", + "PersonalWebsite": "Sito web personale", + "RegistrationDate": "Data di registrazione", + "Social": "Sociale", + "Biography": "Biografia", + "HasNoPublishedArticlesYet": "non ha ancora articoli pubblicati", + "Author": "Autore", + "LatestGithubAnnouncements": "Ultimi annunci su GitHub", + "SeeAllAnnouncements": "Vedi tutti gli annunci", + "LatestBlogPost": "Ultimo post sul blog", + "Edit": "modificare", + "ProfileImageChange": "Cambia l'immagine del profilo", + "BlogItemErrorMessage": "Impossibile ottenere i dettagli più recenti del post del blog da ABP.", + "PlannedReleaseDate": "Data di rilascio prevista", + "CommunityArticleRequestErrorMessage": "Impossibile ottenere l'ultima richiesta di articolo da Github.", + "ArticleRequestFromGithubIssue": "Non ci sono richieste di articoli al momento.", + "LatestArticles": "ultimi post", + "ArticleRequests": "Richieste di articoli", + "AllArticleRequests": "Vedi tutte le richieste di articoli", + "SubscribeToTheNewsletter": "Iscriviti alla Newsletter", + "NewsletterEmailDefinition": "Ottieni informazioni sugli eventi in ABP come nuove versioni, fonti gratuite, articoli e altro ancora.", + "NoThanks": "No grazie", + "MaybeLater": "Forse più tardi", + "JoinOurArticleNewsletter": "Iscriviti alla nostra newsletter articolo", + "Community": "Comunità", + "Marketing": "Marketing", + "CommunityPrivacyPolicyConfirmation": "Accetto i Termini e condizioni e l ' Informativa sulla privacy .", + "ArticleRequestMessageTitle": " Apri un numero su GitHub per richiedere un articolo / tutorial che desideri vedere su questo sito web.", + "ArticleRequestMessageBody": "Di seguito l'elenco degli articoli richiesti dalla community. Vuoi scrivere un articolo richiesto? Fare clic sulla richiesta e partecipare alla discussione.", + "Language": "linguaggio", + "CreateArticleLanguageInfo": "La lingua per il contenuto del post.", + "VideoPost": "Post video", + "Article": "Articolo", + "Read": "Leggere", + "CreateGithubArticleUrlInfo": "URL originale di GitHub dell'articolo.", + "CreateVideoContentUrlInfo": "URL YouTube originale del post.", + "CreateExternalArticleUrlInfo": "URL esterno originale dell'articolo.", + "VideoContentForm": "Invia video su YouTube", + "GithubPostForm": "Invia articolo su GitHub", + "ExternalPostForm": "Invia un contenuto esterno", + "HowToPost": "Come pubblicare?", + "Posts": "Messaggi", + "VideoUrl": "URL video", + "GithubArticleUrl": "URL articolo Github", + "ExternalArticleUrl": "URL articolo esterno", + "CreatePostCoverInfo": "Per creare un post efficace, aggiungi una foto di copertina. Carica immagini in formato 16: 9 per una visualizzazione migliore. Dimensione massima del file: 1 MB.", + "ThankYouForContribution": "Grazie per aver contribuito alla comunità ABP.", + "GithubArticle": "Articolo GitHub", + "GithubArticleSubmitStepOne": " 1. Scrivi un articolo su qualsiasi repository GitHub pubblico con il formato Markdown. esempio ", + "GithubArticleSubmitStepTwo": " 2. Invia l'URL del tuo articolo utilizzando il modulo.", + "GithubArticleSubmitStepThree": " 3. Il tuo articolo verrà visualizzato in questo sito web.", + "YoutubeVideo": "Video Youtube", + "YoutubeVideoSubmitStepOne": " 1. Pubblica il tuo video su YouTube.", + "YoutubeVideoSubmitStepTwo": " 2. Invia l'URL del video utilizzando il modulo.", + "YoutubeVideoSubmitStepThree": " 3. I visitatori potranno guardare i tuoi contenuti video direttamente su questo sito web.", + "ExternalContent": "Contenuto esterno", + "ExternalContentSubmitStepOne": " 1. Crea un contenuto su qualsiasi piattaforma pubblica (mezzo, il tuo blog o ovunque tu voglia).", + "ExternalContentSubmitStepTwo": " 2. Invia l'URL dei tuoi contenuti utilizzando il modulo.", + "ExternalContentSubmitStepThree": " 3. I visitatori vengono reindirizzati al contenuto del sito web originale.", + "ChooseYourContentType": "Scegli il modo in cui desideri aggiungere i tuoi contenuti.", + "PostContentViaGithub": "Voglio aggiungere il mio articolo con GitHub in conformità con le regole di markdown.", + "PostContentViaYoutube": "Voglio condividere i miei video disponibili su Youtube qui.", + "PostContentViaExternalSource": "Voglio aggiungere qui il contenuto che ho pubblicato su un'altra piattaforma .", + "GitHubUserNameValidationMessage": "Il tuo nome utente Github non può includere spazi bianchi, assicurati che il tuo nome utente Github sia corretto.", + "PersonalSiteUrlValidationMessage": "L'URL del tuo sito personale non può includere spazi bianchi, assicurati che l'URL del tuo sito personale sia corretto.", + "TwitterUserNameValidationMessage": "Il tuo nome utente Twitter non può includere spazi bianchi, assicurati che il tuo nome utente Twitter sia corretto.", + "LinkedinUrlValidationMessage": "Il tuo URL di Linkedin non può includere spazi bianchi, assicurati che il tuo URL di Linkedin sia corretto.", + "NoPostsFound": "Nessun post trovato!", + "SearchInPosts": "Cerca nei post ...", + "MinimumSearchContent": "Devi inserire almeno 3 caratteri!", + "Volo.AbpIo.Domain:060001": "L'URL di origine (\"{ArticleUrl}\") non è l'URL di GitHub", + "Volo.AbpIo.Domain:060002": "Il contenuto dell'articolo non è disponibile dalla risorsa Github (\"{ArticleUrl}\").", + "Volo.AbpIo.Domain:060003": "Nessun contenuto dell'articolo trovato!" + } +} \ No newline at end of file diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/en-GB.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/en-GB.json index c0a168a6c2..f99dee2c0e 100644 --- a/abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/en-GB.json +++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/en-GB.json @@ -194,6 +194,41 @@ "MultipleUIOptionsExplanation": "The core framework is designed as UI independent and can work with any type of UI system, while there are multiple pre-built and integrated options are provided out of the box.", "MultipleDBOptionsExplanation": "The framework can work with any data source, while the following providers are officially developed and supported:", "SelectLanguage": "Select language", - "LatestArticleOnCommunity": "Latest Article on ABP Community" + "LatestArticleOnCommunity": "Latest Article on ABP Community", + "Register": "Register", + "IsDownloadable": "Is downloadable", + "DatabaseOptions": "Database Options", + "BackToPackagesPage": "Back to Packages Page", + "HowToInstall": "How to Install", + "SeeOnNpm": "See on NPM", + "SeeOnNuget": "See on Nuget", + "MVCGulpCommandExplanation": "If you are using MVC (Razor Pages) UI, then run the \"gulp\" command after the package installation.", + "UsingABPCLI": "Using Abp CLI", + "WithoutABPCLI": "Without ABP CLI", + "ABPCLIModuleDependency": "Abp Cli automatically adds module dependency.", + "AddModuleDependency": "Then add module dependency", + "Packages": "Packages", + "NugetPackages": "Nuget Packages", + "NPMPackages": "NPM Packages", + "SeeDocs": "See Docs", + "None": "None", + "Application": "Application", + "Module": "Module", + "PackageName": "Package Name", + "LicenseURL": "License URL", + "License": "License", + "ProjectCreationSuccessMessage": "Your project has been successfully created", + "HowToRunSolution": "How to Run Your Solution?", + "GettingStartedMessage": "See getting started document to learn how to configure and run your solution.", + "WebAppDevTutorial": "Web App Dev Tutorial", + "WebAppDevTutorialMessage": "See web application development tutorial document for a step by step development sample.", + "CommunityArticles": "Community Articles", + "CommunityArticleMessage": "Check ABP Community Platform to read useful articles for ABP Framework.", + "InvestigateSolutionDetails": "Investigate the Solution Details", + "StartupTemplateDocumentationMessage": "See application startup template document to learn the architecture and the structure of your solution.", + "ClientSideDevelopment": "Client Side Development", + "ClientSideDevelopmentDocumentationMessage": "See the {0} document to learn key points for user interface (client side) development.", + "DatabaseProviderDocumentationMessage": "See {0} document to learn key points for database layer development.", + "ABPCommercialExplanationMessage": "ABP Commercial provides premium modules, themes, tooling and support for the ABP Framework." } } \ No newline at end of file diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/en.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/en.json index 0edbb7a5dc..a24931dab5 100644 --- a/abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/en.json +++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/en.json @@ -175,7 +175,7 @@ "TieredOption": "Creates a tiered solution where Web and Http API layers are physically separated. If not checked, creates a layered solution which is less complex and suitable for most scenarios.", "SeparateIdentityServerOption": "Separates server side into two applications: First one is for the identity server and the second one is for your server side HTTP API.", "UseslatestPreVersion": "Uses latest pre-release version", - "ReadTheDocumentation": "ReadThe Documentation", + "ReadTheDocumentation": "Read The Documentation", "Documentation": "Documentation", "GettingStartedTutorial": "Getting Started Tutorial", "ApplicationDevelopmentTutorial": "Application Development Tutorial", @@ -195,8 +195,41 @@ "MultipleUIOptionsExplanation": "The core framework is designed as UI independent and can work with any type of UI system, while there are multiple pre-built and integrated options are provided out of the box.", "MultipleDBOptionsExplanation": "The framework can work with any data source, while the following providers are officially developed and supported;", "SelectLanguage": "Select language", - "LatestArticleOnCommunity": "Latest Article on ABP Community", - "Register": "Register", - "IsDownloadable": "Is downloadable" + "LatestArticleOnCommunity": "Latest Article on ABP Community", + "Register": "Register", + "IsDownloadable": "Is downloadable", + "DatabaseOptions": "Database Options", + "BackToPackagesPage": "Back to Packages Page", + "HowToInstall": "How to Install", + "SeeOnNpm": "See on NPM", + "SeeOnNuget": "See on Nuget", + "MVCGulpCommandExplanation": "If you are using MVC (Razor Pages) UI, then run the \"gulp\" command after the package installation.", + "UsingABPCLI": "Using Abp CLI", + "WithoutABPCLI": "Without ABP CLI", + "ABPCLIModuleDependency": "Abp Cli automatically adds module dependency.", + "AddModuleDependency": "Then add module dependency", + "Packages": "Packages", + "NugetPackages": "Nuget Packages", + "NPMPackages": "NPM Packages", + "SeeDocs": "See Docs", + "None": "None", + "Application": "Application", + "Module": "Module", + "PackageName": "Package Name", + "LicenseURL": "License URL", + "License": "License", + "ProjectCreationSuccessMessage": "Your project has been successfully created", + "HowToRunSolution": "How to Run Your Solution?", + "GettingStartedMessage": "See getting started document to learn how to configure and run your solution.", + "WebAppDevTutorial": "Web App Dev Tutorial", + "WebAppDevTutorialMessage": "See web application development tutorial document for a step by step development sample.", + "CommunityArticles": "Community Articles", + "CommunityArticleMessage": "Check ABP Community Platform to read useful articles for ABP Framework.", + "InvestigateSolutionDetails": "Investigate the Solution Details", + "StartupTemplateDocumentationMessage": "See application startup template document to learn the architecture and the structure of your solution.", + "ClientSideDevelopment": "Client Side Development", + "ClientSideDevelopmentDocumentationMessage": "See the {0} document to learn key points for user interface (client side) development.", + "DatabaseProviderDocumentationMessage": "See {0} document to learn key points for database layer development.", + "ABPCommercialExplanationMessage": "ABP Commercial provides premium modules, themes, tooling and support for the ABP Framework." } } diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/FR.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/fr.json similarity index 90% rename from abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/FR.json rename to abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/fr.json index b3b8d3e241..878af5e830 100644 --- a/abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/FR.json +++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/fr.json @@ -42,11 +42,11 @@ "BootstrapTagHelpersDynamicForms": "Aide aux balises Bootstrap et formulaires dynamiques", "BootstrapTagHelpersDynamicFormsExplanation": "Au lieu d'écrire manuellement les détails répétitifs des composants d'amorçage, utilisez les assistants de balises d'ABP pour le simplifier et tirer parti d'intellisense. Créez rapidement des formulaires d'interface utilisateur basés sur un modèle C # à l'aide de l'assistant de balise de formulaire dynamique.", "HTTPAPIsDynamicProxies": "API HTTP et proxys dynamiques", - "HTTPAPIsDynamicProxiesExplanation": "Exposez automatiquement les services d'application en tant qu'API HTTP de style REST et utilisez-les avec des proxys JavaScript et C # dynamiques.", + "HTTPAPIsDynamicProxiesExplanation": "Exposez automatiquement les services d'application en tant qu'API HTTP de style REST et utilisez-les avec des proxys JavaScript et C# dynamiques.", "CompleteArchitectureInfo": "Architecture moderne pour créer des solutions logicielles maintenables.", "DomainDrivenDesignBasedLayeringModelExplanation": "Vous aide à implémenter une architecture en couches basée sur DDD et à créer une base de code maintenable.", "DomainDrivenDesignBasedLayeringModelExplanationCont": "Fournit des modèles de démarrage, des abstractions, des classes de base, des services, de la documentation et des guides pour vous aider à développer votre application basée sur les modèles et principes DDD.", - "MicroserviceCompatibleModelExplanation": "Le cadre de base et les modules de pré-construction sont conçus avec l'architecture de microservice à l'esprit.", + "MicroserviceCompatibleModelExplanation": "Le framework de base et les modules de pré-construction sont conçus avec l'architecture de microservice à l'esprit.", "MicroserviceCompatibleModelExplanationCont": "Fournit une infrastructure, des intégrations, des exemples et de la documentation pour mettre en œuvre des solutions de microservices plus facilement, sans apporter de complexité supplémentaire si vous souhaitez une application monolithique.", "ModularInfo": "ABP fournit un système de modules qui vous permet de développer des modules d'application réutilisables, de les relier aux événements du cycle de vie des applications et d'exprimer les dépendances entre les parties centrales de votre système.", "PreBuiltModulesThemes": "Modules et thèmes prédéfinis", @@ -64,13 +64,13 @@ "TransactionManagement": "Gestion des transactions", "AuditLogging": "Journalisation d'audit", "Caching": "Mise en cache", - "Multitenancy": "Locations multiples", + "Multitenancy": "Multi-souscrivants", "DataFiltering": "Filtrage des données", - "ConventionOverConfiguration": "Convention sur la configuration", + "ConventionOverConfiguration": "Convention plutôt que configuration", "ConventionOverConfigurationExplanation": "ABP implémente par défaut des conventions d'application communes avec une configuration minimale ou nulle.", "ConventionOverConfigurationExplanationList1": "Enregistre automatiquement les services connus pour l'injection de dépendances.", "ConventionOverConfigurationExplanationList2": "Expose les services d'application en tant qu'API HTTP par des conventions de dénomination.", - "ConventionOverConfigurationExplanationList3": "Crée des proxys client HTTP dynamiques pour C # et JavaScript.", + "ConventionOverConfigurationExplanationList3": "Crée des proxys client HTTP dynamiques pour C# et JavaScript.", "ConventionOverConfigurationExplanationList4": "Fournit des référentiels par défaut pour vos entités.", "ConventionOverConfigurationExplanationList5": "Gère l'unité de travail par demande Web ou méthode de service d'application.", "ConventionOverConfigurationExplanationList6": "Publie des événements de création, de mise à jour et de suppression pour vos entités.", @@ -96,7 +96,7 @@ "BackgroundJobs": "Emplois d'arrière-plan", "BackgroundJobsExplanation": "Définissez des classes simples pour exécuter les travaux en arrière-plan comme mis en file d'attente. Utilisez le gestionnaire de tâches intégré ou intégrez le vôtre. Les intégrations Hangfire et RabbitMQ sont déjà disponibles.", "DDDInfrastructure": "Infrastructure DDD", - "DomainDrivenDesignInfrastructure": "Infrastructure de conception pilotée par domaine", + "DomainDrivenDesignInfrastructure": "Infrastructure Domain Driven Design", "AutoRESTAPIs": "API REST automatiques", "DynamicClientProxies": "Proxys clients dynamiques", "DistributedEventBus": "Bus d'événements distribués", @@ -116,12 +116,12 @@ "DependencyInjectionByConventions": "Injection de dépendances par conventions", "ABPCLIExplanation": "ABP CLI (Command Line Interface) est un outil de ligne de commande pour effectuer certaines opérations courantes pour les solutions basées sur ABP.", "ModularityExplanation": "ABP fournit une infrastructure complète pour créer vos propres modules d'application qui peuvent avoir des entités, des services, une intégration de base de données, des API, des composants d'interface utilisateur, etc.", - "MultiTenancyExplanation": "Le framework ABP prend non seulement en charge le développement d'applications multi-locataires, mais rend également votre code pratiquement inconscient de la multi-location.", - "MultiTenancyExplanation2": "Peut déterminer automatiquement le locataire actuel, isoler les données de différents locataires les uns des autres.", - "MultiTenancyExplanation3": "Prend en charge une base de données unique, une base de données par locataire et des approches hybrides.", - "MultiTenancyExplanation4": "Vous vous concentrez sur votre code métier et laissez le framework gérer la multi-location en votre nom.", - "BootstrapTagHelpersExplanation": "Au lieu d'écrire manuellement les détails répétitifs des composants d'amorçage, utilisez les aides de balises d'ABP pour le simplifier et tirer parti d'intellisense. Vous pouvez certainement utiliser Bootstrap chaque fois que vous en avez besoin.", - "DynamicFormsExplanation": "Les assistants dynamiques de formulaire et de balise d'entrée peuvent créer le formulaire complet à partir d'une classe C # comme modèle.", + "MultiTenancyExplanation": "Le framework ABP prend non seulement en charge le développement d'applications multi-souscrivants, mais rend également votre code pratiquement inconscient de la multi-location.", + "MultiTenancyExplanation2": "Peut déterminer automatiquement le souscrivant actuel, isoler les données de différents locataires les uns des autres.", + "MultiTenancyExplanation3": "Prend en charge une base de données unique, une base de données par souscrivant et des approches hybrides.", + "MultiTenancyExplanation4": "Vous vous concentrez sur votre code métier et laissez le framework gérer la multi-souscrivants en votre nom.", + "BootstrapTagHelpersExplanation": "Au lieu d'écrire manuellement les détails répétitifs des composants Boostrap, utilisez les aides de balises d'ABP pour le simplifier et tirer parti d'intellisense. Vous pouvez certainement utiliser Bootstrap chaque fois que vous en avez besoin.", + "DynamicFormsExplanation": "Les assistants dynamiques de formulaire et de balise d'entrée peuvent créer le formulaire complet à partir d'une classe C# comme modèle.", "AuthenticationAuthorizationExplanation": "Options d'authentification et d'autorisation riches intégrées à ASP.NET Core Identity & IdentityServer4. Fournit un système d'autorisation extensible et détaillé.", "CrossCuttingConcernsExplanation": "Ne vous répétez pas pour mettre en œuvre toutes ces choses courantes encore et encore. Concentrez-vous sur votre code métier et laissez ABP les automatiser par des conventions.", "DatabaseConnectionTransactionManagement": "Connexion à la base de données et gestion des transactions", @@ -138,9 +138,9 @@ "DataTransferObject": "Objet de transfert de données", "AggregateRootEntity": "Racine agrégée, entité", "AutoRESTAPIsExplanation": "ABP peut configurer automatiquement vos services d'application en tant que contrôleurs d'API par convention.", - "DynamicClientProxiesExplanation": "Utilisez facilement vos API à partir de clients JavaScript et C #.", + "DynamicClientProxiesExplanation": "Utilisez facilement vos API à partir de clients JavaScript et C#.", "DistributedEventBusWithRabbitMQIntegrationExplanation": "Publiez et consommez facilement des événements distribués à l'aide du bus d'événements distribués intégré avec l'intégration RabbitMQ disponible.", - "TestInfrastructureExplanation": "Le cadre a été développé en pensant aux tests unitaires et d'intégration. Vous fournit des classes de base pour vous faciliter la tâche. Les modèles de démarrage sont pré-configurés pour les tests.", + "TestInfrastructureExplanation": "Le framework a été développé en pensant aux tests unitaires et d'intégration. Vous fournit des classes de base pour vous faciliter la tâche. Les modèles de démarrage sont pré-configurés pour les tests.", "AuditLoggingEntityHistoriesExplanation": "Journalisation d'audit intégrée pour les applications stratégiques. Requête, service, journalisation d'audit au niveau de la méthode et historiques d'entités avec des détails au niveau de la propriété.", "EmailSMSAbstractionsWithTemplatingSupportExplanation": "Les abstractions IEmailSender et ISmsSender découpent la logique de votre application de l'infrastructure. Le système de modèle de courrier électronique avancé permet de créer et de localiser des modèles de courrier électronique et de les utiliser facilement en cas de besoin.", "LocalizationExplanation": "Le système de localisation permet de créer des ressources dans des fichiers JSON simples et de les utiliser pour localiser votre interface utilisateur. Il prend en charge des scénarios avancés tels que l'héritage, les extensions et l'intégration JavaScript tout en étant entièrement compatible avec le système de localisation d'AspNet Core.", @@ -156,13 +156,13 @@ "Result": "Résultat", "SeeTheDocumentForMoreInformation": "Consultez le {0} document pour plus d'informations", "IndexPageHeroSection": " open source Application Web
Framework
pour asp.net core ", - "UiFramework": "Cadre de l'interface utilisateur", + "UiFramework": "Framework de l'interface utilisateur", "EmailAddress": "Adresse e-mail", "Mobile": "Mobile", "ReactNative": "Réagir natif", "Strong": "Fort", "Complete": "Compléter", - "BasedLayeringModel": "Modèle de couches basé", + "BasedLayeringModel": "Modèle basé sur des couches", "Microservice": "Microservice", "Compatible": "Compatible", "MeeTTheABPCommunityInfo": "Notre mission est de créer un environnement où les développeurs peuvent s'entraider avec des articles, des tutoriels, des études de cas, etc. et rencontrer des personnes partageant les mêmes idées.", @@ -192,8 +192,8 @@ "TextTemplatingExplanation": "La création de modèles de texte est utilisée pour rendre le contenu de manière dynamique en fonction d'un modèle et d'un modèle (un objet de données). Par exemple, vous pouvez l'utiliser pour créer des contenus d'e-mail dynamiques avec un modèle prédéfini.", "MultipleUIOptions": "Options d'interface utilisateur multiples", "MultipleDBOptions": "Fournisseurs de bases de données multiples", - "MultipleUIOptionsExplanation": "Le cadre de base est conçu comme indépendant de l'interface utilisateur et peut fonctionner avec tout type de système d'interface utilisateur, tandis que plusieurs options prédéfinies et intégrées sont fournies prêtes à l'emploi.", - "MultipleDBOptionsExplanation": "Le cadre peut fonctionner avec n'importe quelle source de données, tandis que les fournisseurs suivants sont officiellement développés et pris en charge;", + "MultipleUIOptionsExplanation": "Le framework de base est conçu comme indépendant de l'interface utilisateur et peut fonctionner avec tout type de système d'interface utilisateur, tandis que plusieurs options prédéfinies et intégrées sont fournies prêtes à l'emploi.", + "MultipleDBOptionsExplanation": "Le framework peut fonctionner avec n'importe quelle source de données, tandis que les fournisseurs suivants sont officiellement développés et pris en charge;", "SelectLanguage": "Choisir la langue", "LatestArticleOnCommunity": "Dernier article sur la communauté ABP", "Register": "S'inscrire", diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/hi.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/hi.json new file mode 100644 index 0000000000..a7974d8658 --- /dev/null +++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/hi.json @@ -0,0 +1,202 @@ +{ + "culture": "hi", + "texts": { + "GetStarted": "प्रारंभ करें - स्टार्टअप टेम्पलेट", + "Create": "सृजन करना", + "NewProject": "नया काम", + "DirectDownload": "प्रत्यक्षत: डाउनलोड", + "ProjectName": "परियोजना का नाम", + "ProjectType": "प्रोजेक्ट का प्रकार", + "DatabaseProvider": "डेटाबेस प्रदाता", + "DatabaseManagementSystem": "डेटाबेस प्रबंधन प्रणाली", + "NTier": "n स्तरीय", + "IncludeUserInterface": "उपयोगकर्ता इंटरफ़ेस शामिल करें", + "CreateNow": "अब बनाओ", + "TheStartupProject": "स्टार्टअप प्रोजेक्ट", + "Tutorial": "ट्यूटोरियल", + "UsingCLI": "सीएलआई का उपयोग करना", + "SeeDetails": "विवरण देखें", + "AbpShortDescription": "एबीपी फ्रेमवर्क सॉफ्टवेयर विकास सर्वोत्तम प्रथाओं और सम्मेलनों का पालन करके आधुनिक वेब एप्लिकेशन बनाने के लिए एक पूर्ण बुनियादी ढांचा है।", + "SourceCodeUpper": "सोर्स कोड", + "LatestReleaseLogs": "नवीनतम रिलीज़ लॉग", + "Infrastructure": "भूमिकारूप व्यवस्था", + "Architecture": "आर्किटेक्चर", + "Modular": "मॉड्यूलर", + "DontRepeatYourself": "खुद को दोहराएं नहीं", + "DeveloperFocused": "डेवलपर ने फोकस किया", + "FullStackApplicationInfrastructure": "पूर्ण स्टैक अनुप्रयोग अवसंरचना।", + "DomainDrivenDesign": "डोमेन संचालित डिजाइन", + "DomainDrivenDesignExplanation": "डीडीडी पैटर्न और सिद्धांतों के आधार पर डिजाइन और विकसित। आपके आवेदन के लिए एक स्तरित मॉडल प्रदान करता है।", + "Authorization": "प्राधिकार", + "AuthorizationExplanation": "उपयोगकर्ता, भूमिका और ठीक-ठीक अनुमति प्रणाली के साथ उन्नत प्राधिकरण। Microsoft पहचान लाइब्रेरी पर बनाया गया।", + "MultiTenancy": "बहु किरायेदारी", + "MultiTenancyExplanationShort": "सास अनुप्रयोगों आसान बना दिया! यूआई के लिए डेटाबेस से एकीकृत मल्टी-टेनेंसी।", + "CrossCuttingConcerns": "फिल्म आदि में दृश्यों के संपादन संबंधी चिंताएं", + "CrossCuttingConcernsExplanationShort": "प्राधिकरण, सत्यापन, अपवाद से निपटने, कैशिंग, ऑडिट लॉगिंग, लेनदेन प्रबंधन और बहुत कुछ के लिए पूरा बुनियादी ढांचा।", + "BuiltInBundlingMinification": "अंतर्निहित बंडलिंग और न्यूनतम", + "BuiltInBundlingMinificationExplanation": "बंडलिंग और लघुकरण के लिए बाहरी उपकरणों का उपयोग करने की आवश्यकता नहीं है। ABP एक सरल, गतिशील, शक्तिशाली, मॉड्यूलर और बिल्ट-इन तरीका प्रदान करता है!", + "VirtualFileSystem": "वर्चुअल फाइल सिस्टम", + "VirtualFileSystemExplanation": "पैकेज, पुस्तकालयों में विचार, स्क्रिप्ट, शैली, चित्र एम्बेड करें और विभिन्न अनुप्रयोगों में उनका पुन: उपयोग करें।", + "Theming": "थीम", + "ThemingExplanationShort": "बूटस्ट्रैप-आधारित मानक UI थीम का उपयोग करें और अनुकूलित करें या अपना स्वयं का बनाएं।", + "BootstrapTagHelpersDynamicForms": "बूटस्ट्रैप टैग हेल्पर्स और डायनामिक फॉर्म", + "BootstrapTagHelpersDynamicFormsExplanation": "बूटस्ट्रैप घटकों के दोहराए गए विवरणों को मैन्युअल रूप से लिखने के बजाय, इसे सरल बनाने और अंतरंगता का लाभ उठाने के लिए एबीपी के टैग सहायकों का उपयोग करें। डायनामिक फॉर्म टैग हेल्पर का उपयोग करके C # मॉडल के आधार पर जल्दी से UI फॉर्म का निर्माण करें।", + "HTTPAPIsDynamicProxies": "HTTP एपीआई और डायनेमिक प्रॉक्सी", + "HTTPAPIsDynamicProxiesExplanation": "REST शैली HTTP API के रूप में एप्लिकेशन सेवाओं को स्वचालित रूप से उजागर करें, और उन्हें गतिशील जावास्क्रिप्ट और C # प्रॉक्सी के साथ उपभोग करें।", + "CompleteArchitectureInfo": "बनाए रखने योग्य सॉफ़्टवेयर समाधान बनाने के लिए आधुनिक वास्तुकला।", + "DomainDrivenDesignBasedLayeringModelExplanation": "डीडीडी आधारित स्तरित वास्तुकला को लागू करने और बनाए रखने योग्य कोड आधार बनाने में आपकी सहायता करता है।", + "DomainDrivenDesignBasedLayeringModelExplanationCont": "DDD पैटर्न और सिद्धांतों के आधार पर आपके एप्लिकेशन को विकसित करने में मदद करने के लिए स्टार्टअप टेम्प्लेट, सार, आधार कक्षाएं, सेवाएं, प्रलेखन और मार्गदर्शिका प्रदान करता है।", + "MicroserviceCompatibleModelExplanation": "कोर फ्रेमवर्क और प्री-बिल्ड मॉड्यूल को दिमाग में माइक्रोसैस आर्किटेक्चर के साथ डिजाइन किया गया है।", + "MicroserviceCompatibleModelExplanationCont": "यदि आप एक अखंड आवेदन चाहते हैं, तो यह आसान नहीं है कि माइक्रोसॉफ़्ट समाधानों को लागू करने के लिए बुनियादी ढाँचा, एकीकरण, नमूने और प्रलेखन प्रदान करता है।", + "ModularInfo": "एबीपी एक मॉड्यूल प्रणाली प्रदान करता है जो आपको पुन: प्रयोज्य एप्लिकेशन मॉड्यूल विकसित करने, एप्लिकेशन जीवन चक्र घटनाओं में टाई करने और आपके सिस्टम के मुख्य भागों के बीच निर्भरता व्यक्त करने की अनुमति देता है।", + "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 APIs के रूप में अनुप्रयोग सेवाओं का प्रस्ताव है।", + "ConventionOverConfigurationExplanationList3": "C # और JavaScript के लिए गतिशील HTTP क्लाइंट प्रॉक्सी बनाता है।", + "ConventionOverConfigurationExplanationList4": "आपकी संस्थाओं के लिए डिफ़ॉल्ट रिपॉजिटरी प्रदान करता है।", + "ConventionOverConfigurationExplanationList5": "वेब अनुरोध या एप्लिकेशन सेवा पद्धति के अनुसार कार्य की इकाई का प्रबंधन।", + "ConventionOverConfigurationExplanationList6": "आपकी संस्थाओं के लिए ईवेंट बनाएं, अपडेट करें और हटाएं।", + "BaseClasses": "आधार वर्ग", + "BaseClassesExplanation": "सामान्य अनुप्रयोग पैटर्न के लिए पूर्व-निर्मित आधार कक्षाएं।", + "DeveloperFocusedExplanation": "एबीपी डेवलपर्स के लिए है।", + "DeveloperFocusedExplanationCont": "यह आपके दैनिक सॉफ्टवेयर विकास को सरल बनाने का लक्ष्य रखता है जबकि आपको निम्न स्तर के कोड लिखने से प्रतिबंधित नहीं करता है।", + "SeeAllFeatures": "सभी सुविधाएँ देखें", + "CLI_CommandLineInterface": "सीएलआई (कमांड लाइन इंटरफ़ेस)", + "CLI_CommandLineInterfaceExplanation": "नई परियोजनाओं के निर्माण और नए मॉड्यूल को जोड़ने में मदद करने के लिए एक CLI शामिल है।", + "StartupTemplates": "स्टार्टअप टेम्पलेट", + "StartupTemplatesExplanation": "विभिन्न स्टार्टअप टेम्प्लेट आपके विकास को शुरू करने के लिए पूरी तरह से कॉन्फ़िगर समाधान प्रदान करते हैं।", + "BasedOnFamiliarTools": "परिचित उपकरणों के आधार पर", + "BasedOnFamiliarToolsExplanation": "आप पहले से ही जानते हैं कि लोकप्रिय उपकरणों के साथ निर्मित और एकीकृत। कम सीखने की अवस्था, आसान अनुकूलन, आरामदायक विकास।", + "ORMIndependent": "ORM स्वतंत्र", + "ORMIndependentExplanation": "कोर फ्रेमवर्क ORM / डेटाबेस स्वतंत्र है और किसी भी डेटा स्रोत के साथ काम कर सकता है। इकाई फ्रेमवर्क कोर और MongoDB प्रदाता पहले से ही उपलब्ध हैं।", + "Features": "ABP फ्रेमवर्क सुविधाओं का अन्वेषण करें", + "ABPCLI": "एबीपी सीएलआई", + "Modularity": "प्रतिरूपकता", + "BootstrapTagHelpers": "बूटस्ट्रैप टैग हेल्पर्स", + "DynamicForms": "गतिशील रूप", + "BundlingMinification": "बंडलिंग और न्यूनतमकरण", + "BackgroundJobs": "बैकग्राउंड जॉब्स", + "BackgroundJobsExplanation": "सरल कक्षाओं को परिभाषित करें ताकि पृष्ठभूमि में नौकरियों को निष्पादित किया जा सके। अंतर्निहित नौकरी प्रबंधक का उपयोग करें या अपने स्वयं के एकीकृत करें। Hangfire और RabbitMQ एकीकरण पहले से ही उपलब्ध हैं।", + "DDDInfrastructure": "डीडीडी इन्फ्रास्ट्रक्चर", + "DomainDrivenDesignInfrastructure": "डोमेन संचालित डिज़ाइन इन्फ्रास्ट्रक्चर", + "AutoRESTAPIs": "ऑटो रीस्ट एपीआई", + "DynamicClientProxies": "गतिशील ग्राहक प्रॉक्सी", + "DistributedEventBus": "वितरित इवेंट बस", + "DistributedEventBusWithRabbitMQIntegration": "रैबिटएमक्यू इंटीग्रेशन वाली इवेंट बस वितरित की", + "TestInfrastructure": "टेस्ट इन्फ्रास्ट्रक्चर", + "AuditLoggingEntityHistories": "ऑडिट लॉगिंग और इकाई इतिहास", + "ObjectToObjectMapping": "ऑब्जेक्ट टू ऑब्जेक्ट मैपिंग", + "ObjectToObjectMappingExplanation": "AutoMapper एकीकरण के साथ अमूर्तता के लिए ऑब्जेक्ट मैपिंग पर ऑब्जेक्ट ।", + "EmailSMSAbstractions": "ईमेल और एसएमएस अंश", + "EmailSMSAbstractionsWithTemplatingSupport": "ईमेल और एसएमएस अंशांकन समर्थन के साथ", + "Localization": "स्थानीयकरण", + "SettingManagement": "प्रबंधन की स्थापना", + "ExtensionMethods": "एक्सटेंशन के तरीके", + "ExtensionMethodsHelpers": "एक्सटेंशन के तरीके और मददगार", + "AspectOrientedProgramming": "पहलू आधारित प्रोग्रामिंग", + "DependencyInjection": "निर्भरता अन्तःक्षेपण", + "DependencyInjectionByConventions": "सम्मेलनों द्वारा निर्भरता इंजेक्शन", + "ABPCLIExplanation": "ABP CLI (कमांड लाइन इंटरफेस) ABP आधारित समाधानों के लिए कुछ सामान्य ऑपरेशन करने के लिए एक कमांड लाइन टूल है।", + "ModularityExplanation": "ABP अपने स्वयं के एप्लिकेशन मॉड्यूल बनाने के लिए एक पूर्ण बुनियादी ढांचा प्रदान करता है जिनके पास इकाइयाँ, सेवाएँ, डेटाबेस एकीकरण, API, UI घटक और इतने पर हो सकता है।", + "MultiTenancyExplanation": "एबीपी फ्रेमवर्क न केवल बहु-किरायेदार अनुप्रयोगों को विकसित करने का समर्थन करता है, बल्कि आपके कोड को बहु-किरायेदारी से अनजान बनाता है।", + "MultiTenancyExplanation2": "वर्तमान किरायेदार को स्वचालित रूप से निर्धारित कर सकते हैं, एक दूसरे से अलग किरायेदारों के डेटा को अलग कर सकते हैं।", + "MultiTenancyExplanation3": "एकल डेटाबेस, डेटाबेस प्रति किरायेदार और हाइब्रिड दृष्टिकोण का समर्थन करता है।", + "MultiTenancyExplanation4": "आप अपने व्यवसाय कोड पर ध्यान केंद्रित करते हैं और आपकी ओर से मल्टी-टेनेंसी को संभालने की रूपरेखा तैयार करते हैं।", + "BootstrapTagHelpersExplanation": "बूटस्ट्रैप घटकों के दोहराए गए विवरणों को मैन्युअल रूप से लिखने के बजाय, इसे सरल बनाने और अंतरंगता का लाभ उठाने के लिए एबीपी के टैग सहायकों का उपयोग करें। जब भी आपको जरूरत हो आप बूटस्ट्रैप का इस्तेमाल जरूर कर सकते हैं।", + "DynamicFormsExplanation": "डायनामिक फॉर्म और इनपुट टैग हेल्पर्स मॉडल के रूप में C # क्लास से पूरा फॉर्म बना सकते हैं।", + "AuthenticationAuthorizationExplanation": "रिच प्रमाणीकरण और प्राधिकरण विकल्प ASP.NET कोर आइडेंटिटी और आइडेंटिटी सेवर 4 को एकीकृत करता है। एक एक्स्टेंसिबल और विस्तृत अनुमति प्रणाली प्रदान करता है।", + "CrossCuttingConcernsExplanation": "इन सभी सामान्य चीज़ों को बार-बार लागू करने के लिए अपने आप को दोहराएं नहीं। अपने व्यवसाय कोड पर ध्यान दें और एबीपी को उन्हें सम्मेलनों द्वारा स्वचालित करें।", + "DatabaseConnectionTransactionManagement": "डेटाबेस कनेक्शन और लेनदेन प्रबंधन", + "CorrelationIdTracking": "सहसंबंध-आईडी ट्रैकिंग", + "BundlingMinificationExplanation": "ABP एक सरल, गतिशील, शक्तिशाली, मॉड्यूलर और बिल्ट-इन बंडलिंग और मिनिफिकेशन सिस्टम प्रदान करता है।", + "VirtualFileSystemnExplanation": "वर्चुअल फ़ाइल सिस्टम उन फ़ाइलों को प्रबंधित करना संभव बनाता है जो फ़ाइल सिस्टम (डिस्क) पर भौतिक रूप से मौजूद नहीं हैं। यह मुख्य रूप से विधानसभाओं में (js, css, image, cshtml ...) फ़ाइलों को एम्बेड करने और रनटाइम के दौरान भौतिक फ़ाइलों की तरह उपयोग करने के लिए उपयोग किया जाता है।", + "ThemingExplanation": "थिमिंग सिस्टम नवीनतम बूटस्ट्रैप ढांचे के आधार पर, सामान्य आधार पुस्तकालयों और लेआउट के एक सेट को परिभाषित करके आपके एप्लिकेशन और मॉड्यूल विषय को विकसित करने की अनुमति देता है।", + "DomainDrivenDesignInfrastructureExplanation": "डोमेन संचालित डिज़ाइन पैटर्न और सिद्धांतों के आधार पर स्तरित अनुप्रयोगों के निर्माण के लिए एक पूर्ण बुनियादी ढांचा;", + "Specification": "विनिर्देश", + "Repository": "कोष", + "DomainService": "डोमेन सेवा", + "ValueObject": "मान वस्तु", + "ApplicationService": "आवेदन सेवा", + "DataTransferObject": "डेटा ट्रांसफर ऑब्जेक्ट", + "AggregateRootEntity": "एग्रिगेट रूट, एंटिटी", + "AutoRESTAPIsExplanation": "एबीपी कन्वेंशन द्वारा एपीआई कंट्रोलर के रूप में आपकी एप्लिकेशन सेवाओं को स्वचालित रूप से कॉन्फ़िगर कर सकता है।", + "DynamicClientProxiesExplanation": "आसानी से जावास्क्रिप्ट और सी # क्लाइंट से अपने एपीआई का उपभोग करें।", + "DistributedEventBusWithRabbitMQIntegrationExplanation": "बिल्ट-इन डिस्ट्रीब्यूटेड इवेंट बस का उपयोग करके आसानी से प्रकाशित और उपभोग की गई घटनाओं को उपलब्ध करें।", + "TestInfrastructureExplanation": "फ्रेमवर्क को यूनिट और एकीकरण परीक्षण को ध्यान में रखते हुए विकसित किया गया है। यह आसान बनाने के लिए आपको आधार कक्षाएं प्रदान करता है। स्टार्टअप टेम्प्लेट परीक्षण के लिए पूर्व-कॉन्फ़िगर के साथ आते हैं।", + "AuditLoggingEntityHistoriesExplanation": "व्यावसायिक महत्वपूर्ण अनुप्रयोगों के लिए अंतर्निहित ऑडिट लॉगिंग। संपत्ति स्तर के विवरण के साथ अनुरोध, सेवा, विधि स्तर ऑडिट लॉगिंग और इकाई इतिहास।", + "EmailSMSAbstractionsWithTemplatingSupportExplanation": "IEmailSender और ISmsSender अमूर्त बुनियादी ढांचे से आपके आवेदन के तर्क को विघटित करते हैं। उन्नत ईमेल टेम्प्लेट सिस्टम ईमेल टेम्प्लेट बनाने और स्थानीय बनाने और जब भी आवश्यकता हो आसानी से उपयोग करने की अनुमति देता है।", + "LocalizationExplanation": "स्थानीयकरण प्रणाली सादे JSON फ़ाइलों में संसाधन बनाने और उन्हें आपके UI को स्थानीय बनाने के लिए उपयोग करने की अनुमति देती है। यह वंशानुक्रम, एक्सटेंशन और जावास्क्रिप्ट एकीकरण जैसे उन्नत परिदृश्यों का समर्थन करता है, जबकि यह AspNet Core के स्थानीयकरण प्रणाली के साथ पूरी तरह से संगत है।", + "SettingManagementExplanation": "अपने आवेदन के लिए सेटिंग्स को परिभाषित करें और वर्तमान कॉन्फ़िगरेशन, किरायेदार और उपयोगकर्ता के आधार पर रनटाइम पर मान प्राप्त करें।", + "ExtensionMethodsHelpersExplanation": "तुच्छ कोड भागों के लिए भी अपने आप को दोहराएं नहीं। मानक प्रकारों के लिए एक्सटेंशन और हेल्पर्स आपके कोड को बहुत क्लीनर और लिखने में आसान बनाते हैं।", + "AspectOrientedProgrammingExplanation": "गतिशील परदे के पीछे बनाने और पहलू ओरिएंटेड प्रोग्रामिंग को लागू करने के लिए एक आरामदायक बुनियादी ढांचा प्रदान करता है। किसी भी वर्ग को इंटरसेप्ट करें और हर विधि के निष्पादन से पहले और बाद में अपने कोड को निष्पादित करें।", + "DependencyInjectionByConventionsExplanation": "मैन्युअल रूप से निर्भरता इंजेक्शन के लिए अपनी कक्षाओं को पंजीकृत करने की आवश्यकता नहीं है। कन्वेंशन द्वारा स्वचालित रूप से आम सेवा प्रकारों को पंजीकृत करता है। अन्य प्रकार की सेवाओं के लिए, आप इसे आसान और सरल बनाने के लिए इंटरफेस और विशेषताओं का उपयोग कर सकते हैं।", + "DataFilteringExplanation": "उन डेटा फ़िल्टर को परिभाषित और उपयोग करें जो डेटाबेस से क्वेरी करने पर स्वचालित रूप से लागू होते हैं। जब आप साधारण इंटरफ़ेस लागू करते हैं, तो सॉफ्ट डिलीट और मल्टीटेन्नेर फिल्टर बॉक्स से बाहर दिए जाते हैं।", + "PublishEvents": "घटनाक्रम प्रकाशित करें", + "HandleEvents": "घटनाएँ संभालें", + "AndMore": "और अधिक...", + "Code": "कोड", + "Result": "परिणाम", + "SeeTheDocumentForMoreInformation": "अधिक जानकारी के लिए {0} दस्तावेज़ देखें", + "IndexPageHeroSection": "<स्पैन क्लास = \"फर्स्ट-लाइन शाइन\"> ओपन सोर्स <स्पैन क्लास = \"सेकंड-लाइन टेक्स्ट-अपरकेस\"> वेब एप्लिकेशन
फ्रेमवर्क asp.net core के लिए ", + "UiFramework": "यूआई फ्रेमवर्क", + "EmailAddress": "ईमेल पता", + "Mobile": "मोबाइल", + "ReactNative": "प्रतिक्रियाशील मूलनिवासी", + "Strong": "मजबूत", + "Complete": "पूर्ण", + "BasedLayeringModel": "आधारित लेयरिंग मॉडल", + "Microservice": "माइक्रो सर्विस", + "Compatible": "संगत", + "MeeTTheABPCommunityInfo": "हमारा मिशन एक ऐसा वातावरण बनाना है जहां डेवलपर्स लेख, ट्यूटोरियल, केस स्टडी आदि के साथ एक-दूसरे की मदद कर सकें और समान विचारधारा वाले लोगों से मिल सकें।", + "JoinTheABPCommunityInfo": "एक जीवंत समुदाय के साथ शामिल हों और ABP फ्रेमवर्क में योगदानकर्ता बनें!", + "AllArticles": "सभी चीज़ें", + "SubmitYourArticle": "अपना लेख प्रस्तुत करें", + "DynamicClientProxyDocument": " JavaScript और C # के लिए डायनेमिक क्लाइंट प्रॉक्सी दस्तावेज़ देखें।", + "EmailSMSAbstractionsDocument": "अधिक जानकारी के लिए ईमेल करना और एसएमएस भेजने के दस्तावेज़ देखें।", + "CreateProjectWizard": "यह विज़ार्ड स्टार्टअप टेम्प्लेट से एक नई परियोजना बनाता है जो आपकी परियोजना को शुरू करने के लिए ठीक से कॉन्फ़िगर किया गया है।", + "TieredOption": "एक ऐसा समाधान तैयार करता है जहाँ वेब और Http API परतें शारीरिक रूप से अलग हो जाती हैं। यदि जांच नहीं की जाती है, तो एक स्तरित समाधान बनाता है जो कम जटिल है और अधिकांश परिदृश्यों के लिए उपयुक्त है।", + "SeparateIdentityServerOption": "सर्वर एप्लिकेशन को दो अनुप्रयोगों में अलग करता है: पहला पहचान सर्वर के लिए है और दूसरा आपके सर्वर साइड HTTP एपीआई के लिए है।", + "UseslatestPreVersion": "नवीनतम पूर्व-रिलीज़ संस्करण का उपयोग करता है", + "ReadTheDocumentation": "<स्पैन क्लास = \"टेक्स्ट-प्राइमरी\"> पढ़ें <स्पैन क्लास = \"टेक्स्ट-सक्सेस\"> डॉक्यूमेंटेशन ", + "Documentation": "प्रलेखन", + "GettingStartedTutorial": "स्टार्टिंग ट्यूटोरियल", + "ApplicationDevelopmentTutorial": "अनुप्रयोग विकास ट्यूटोरियल", + "TheStartupTemplate": "स्टार्टअप टेम्पलेट", + "InstallABPCLIInfo": "एबीपी सीएलआई एबीपी ढांचे के साथ एक नया समाधान शुरू करने का सबसे तेज़ तरीका है। कमांड लाइन विंडो का उपयोग करके ABP CLI स्थापित करें:", + "DifferentLevelOfNamespaces": "आप विभिन्न स्तरों के नामस्थानों का उपयोग कर सकते हैं; जैसे BookStore, Acme.BookStore या Acme.Retail.BookStore।", + "ABPCLIExamplesInfo": " नया कमांड डेटाबेस प्रदाता के रूप में एंटिटी फ्रेमवर्क कोर के साथ स्तरित MVC एप्लिकेशन बनाता है। हालांकि, इसके पास अतिरिक्त विकल्प हैं। उदाहरण:", + "SeeCliDocumentForMoreInformation": "अधिक विकल्पों के लिए ABP CLI दस्तावेज़ देखें या ऊपर \"डायरेक्ट डाउनलोड\" टैब चुनें।", + "Optional": "ऐच्छिक", + "LocalFrameworkRef": "फ्रेमवर्क पैकेज के लिए स्थानीय प्रोजेक्ट संदर्भ रखें।", + "BlobStoring": "ब्लॉब भंडारण", + "BlobStoringExplanation": "BLOB भंडारण प्रणाली BLOBs के साथ काम करने के लिए एक अमूर्तता प्रदान करती है। एबीपी कुछ प्री-बिल्ट स्टोरेज प्रोवाइडर इंटीग्रेशन (एज़्योर, एडब्ल्यूएस, फाइल सिस्टम, डेटाबेस इत्यादि) प्रदान करता है जिन्हें आप आसानी से अपने अनुप्रयोगों में उपयोग कर सकते हैं।", + "TextTemplating": "पाठ अस्थायी", + "TextTemplatingExplanation": "टेम्प्लेट टेम्प्लेटिंग का उपयोग टेम्प्लेट और मॉडल (डेटा ऑब्जेक्ट) के आधार पर सामग्री को गतिशील रूप से प्रस्तुत करने के लिए किया जाता है। उदाहरण के लिए, आप पूर्व-निर्मित टेम्पलेट के साथ गतिशील ईमेल सामग्री बनाने के लिए इसका उपयोग कर सकते हैं।", + "MultipleUIOptions": "एकाधिक यूआई विकल्प", + "MultipleDBOptions": "एकाधिक डेटाबेस प्रदाता", + "MultipleUIOptionsExplanation": "कोर फ्रेमवर्क को यूआई स्वतंत्र के रूप में डिज़ाइन किया गया है और यह किसी भी प्रकार के यूआई सिस्टम के साथ काम कर सकता है, जबकि कई पूर्व-निर्मित और एकीकृत विकल्प बॉक्स से बाहर प्रदान किए गए हैं।", + "MultipleDBOptionsExplanation": "रूपरेखा किसी भी डेटा स्रोत के साथ काम कर सकती है, जबकि निम्नलिखित प्रदाता आधिकारिक रूप से विकसित और समर्थित हैं;", + "SelectLanguage": "भाषा का चयन करें", + "LatestArticleOnCommunity": "एबीपी समुदाय पर नवीनतम लेख", + "Register": "रजिस्टर करें", + "IsDownloadable": "डाउनलोड करने योग्य है" + } +} \ No newline at end of file diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/it.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/it.json new file mode 100644 index 0000000000..e4cdc73bf2 --- /dev/null +++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/it.json @@ -0,0 +1,202 @@ +{ + "culture": "it", + "texts": { + "GetStarted": "Inizia - Modelli di avvio", + "Create": "Creare", + "NewProject": "Nuovo progetto", + "DirectDownload": "Download diretto", + "ProjectName": "Nome del progetto", + "ProjectType": "Tipo di progetto", + "DatabaseProvider": "Provider di database", + "DatabaseManagementSystem": "Sistema di gestione del database", + "NTier": "N-Tier", + "IncludeUserInterface": "Includi l'interfaccia utente", + "CreateNow": "Crea adesso", + "TheStartupProject": "Il progetto di avvio", + "Tutorial": "Tutorial", + "UsingCLI": "Utilizzo della CLI", + "SeeDetails": "Vedi i dettagli", + "AbpShortDescription": "ABP Framework è un'infrastruttura completa per creare applicazioni Web moderne seguendo le migliori pratiche e convenzioni di sviluppo software.", + "SourceCodeUpper": "CODICE SORGENTE", + "LatestReleaseLogs": "Ultimi registri di rilascio", + "Infrastructure": "Infrastruttura", + "Architecture": "Architettura", + "Modular": "Modulare", + "DontRepeatYourself": "Non ripetere te stesso", + "DeveloperFocused": "Concentrato sullo sviluppatore", + "FullStackApplicationInfrastructure": "Infrastruttura applicativa full stack.", + "DomainDrivenDesign": "Progettazione basata sul dominio", + "DomainDrivenDesignExplanation": "Progettato e sviluppato sulla base di modelli e principi DDD. Fornisce un modello a più livelli per la tua applicazione.", + "Authorization": "Autorizzazione", + "AuthorizationExplanation": "Autorizzazione avanzata con utente, ruolo e sistema di autorizzazioni granulare. Basato sulla libreria Microsoft Identity.", + "MultiTenancy": "Multi-Tenancy", + "MultiTenancyExplanationShort": "Applicazioni SaaS rese facili! Multi-tenancy integrato dal database all'interfaccia utente.", + "CrossCuttingConcerns": "Preoccupazioni trasversali", + "CrossCuttingConcernsExplanationShort": "Infrastruttura completa per autorizzazione, convalida, gestione delle eccezioni, memorizzazione nella cache, registrazione di audit, gestione delle transazioni e altro ancora.", + "BuiltInBundlingMinification": "Raggruppamento e minimizzazione incorporati", + "BuiltInBundlingMinificationExplanation": "Non è necessario utilizzare strumenti esterni per raggruppare e minimizzare. ABP offre un modo più semplice, dinamico, potente, modulare e integrato!", + "VirtualFileSystem": "File system virtuale", + "VirtualFileSystemExplanation": "Incorpora viste, script, stili, immagini ... in pacchetti / librerie e riutilizzali in diverse applicazioni.", + "Theming": "Theming", + "ThemingExplanationShort": "Usa e personalizza il tema dell'interfaccia utente standard basato su bootstrap o creane uno tuo.", + "BootstrapTagHelpersDynamicForms": "Bootstrap Tag Helpers e moduli dinamici", + "BootstrapTagHelpersDynamicFormsExplanation": "Invece di scrivere manualmente i dettagli ripetuti dei componenti bootstrap, usa gli helper tag di ABP per semplificarlo e sfruttare intellisense. Crea rapidamente moduli dell'interfaccia utente basati su un modello C # utilizzando l'helper tag del modulo dinamico.", + "HTTPAPIsDynamicProxies": "API HTTP e proxy dinamici", + "HTTPAPIsDynamicProxiesExplanation": "Esponi automaticamente i servizi dell'applicazione come API HTTP in stile REST e utilizzali con JavaScript dinamici e proxy C #.", + "CompleteArchitectureInfo": "Architettura moderna per creare soluzioni software manutenibili.", + "DomainDrivenDesignBasedLayeringModelExplanation": "Aiuta a implementare un'architettura a strati basata su DDD e a costruire una base di codice gestibile.", + "DomainDrivenDesignBasedLayeringModelExplanationCont": "Fornisce modelli di avvio, astrazioni, classi di base, servizi, documentazione e guide per aiutarti a sviluppare la tua applicazione in base a modelli e principi DDD.", + "MicroserviceCompatibleModelExplanation": "Il framework principale ei moduli di pre-compilazione sono progettati pensando all'architettura dei microservizi.", + "MicroserviceCompatibleModelExplanationCont": "Fornisce infrastruttura, integrazioni, campioni e documentazione per implementare più facilmente soluzioni di microservizi, mentre non apporta ulteriore complessità se si desidera un'applicazione monolitica.", + "ModularInfo": "ABP fornisce un sistema di moduli che consente di sviluppare moduli applicativi riutilizzabili, collegarsi agli eventi del ciclo di vita dell'applicazione ed esprimere le dipendenze tra le parti principali del sistema.", + "PreBuiltModulesThemes": "Moduli e temi predefiniti", + "PreBuiltModulesThemesExplanation": "Moduli e temi open source e commerciali sono pronti per l'uso nella tua applicazione aziendale.", + "NuGetNPMPackages": "Pacchetti NuGet e NPM", + "NuGetNPMPackagesExplanation": "Distribuito come pacchetti NuGet e NPM. Facile da installare e aggiornare.", + "ExtensibleReplaceable": "Estensibile / sostituibile", + "ExtensibleReplaceableExplanation": "Tutti i servizi e i moduli sono progettati tenendo conto dell'estensibilità. Puoi sostituire servizi, pagine, stili e componenti.", + "CrossCuttingConcernsExplanation2": "Mantieni la tua base di codice più piccola in modo da poter concentrarti sul codice specifico per la tua attività.", + "CrossCuttingConcernsExplanation3": "Non dedicare tempo all'implementazione dei requisiti delle applicazioni comuni su più progetti.", + "AuthenticationAuthorization": "Autenticazione e autorizzazione", + "ExceptionHandling": "La gestione delle eccezioni", + "Validation": "Validazione", + "DatabaseConnection": "Connessione al database", + "TransactionManagement": "Gestione delle transazioni", + "AuditLogging": "Registrazione di audit", + "Caching": "Caching", + "Multitenancy": "Multitenancy", + "DataFiltering": "Filtraggio dei dati", + "ConventionOverConfiguration": "Convenzione sulla configurazione", + "ConventionOverConfigurationExplanation": "ABP implementa convenzioni di applicazioni comuni per impostazione predefinita con una configurazione minima o zero.", + "ConventionOverConfigurationExplanationList1": "Registra automaticamente i servizi noti per l'inserimento delle dipendenze.", + "ConventionOverConfigurationExplanationList2": "Espone i servizi dell'applicazione come API HTTP mediante convenzioni di denominazione.", + "ConventionOverConfigurationExplanationList3": "Crea proxy client HTTP dinamici per C # e JavaScript.", + "ConventionOverConfigurationExplanationList4": "Fornisce archivi predefiniti per le tue entità.", + "ConventionOverConfigurationExplanationList5": "Gestisce l'unità di lavoro per richiesta Web o metodo di servizio dell'applicazione.", + "ConventionOverConfigurationExplanationList6": "Pubblica creare, aggiornare ed eliminare eventi per le tue entità.", + "BaseClasses": "Classi di base", + "BaseClassesExplanation": "Classi di base predefinite per modelli di applicazioni comuni.", + "DeveloperFocusedExplanation": "ABP è per gli sviluppatori.", + "DeveloperFocusedExplanationCont": "Ha lo scopo di semplificare lo sviluppo quotidiano del software senza impedirti di scrivere codice di basso livello.", + "SeeAllFeatures": "Visualizza tutte le funzionalità", + "CLI_CommandLineInterface": "CLI (Command Line Interface)", + "CLI_CommandLineInterfaceExplanation": "Include una CLI per aiutarti ad automatizzare la creazione di nuovi progetti e l'aggiunta di nuovi moduli.", + "StartupTemplates": "Modelli di avvio", + "StartupTemplatesExplanation": "Vari modelli di avvio forniscono una soluzione completamente configurata per avviare rapidamente lo sviluppo.", + "BasedOnFamiliarTools": "Basato su strumenti familiari", + "BasedOnFamiliarToolsExplanation": "Costruito e integrato con strumenti popolari che già conosci. Bassa curva di apprendimento, facile adattamento, sviluppo confortevole.", + "ORMIndependent": "ORM indipendente", + "ORMIndependentExplanation": "Il framework principale è indipendente da ORM / database e può funzionare con qualsiasi origine dati. I provider di Entity Framework Core e MongoDB sono già disponibili.", + "Features": "Esplora le funzionalità di ABP Framework", + "ABPCLI": "ABP CLI", + "Modularity": "Modularità", + "BootstrapTagHelpers": "Bootstrap Tag Helpers", + "DynamicForms": "Forme dinamiche", + "BundlingMinification": "Raggruppamento e minimizzazione", + "BackgroundJobs": "Lavori in background", + "BackgroundJobsExplanation": "Definire classi semplici per eseguire lavori in background come in coda. Usa il gestore dei lavori integrato o integra il tuo. Le integrazioni Hangfire e RabbitMQ sono già disponibili.", + "DDDInfrastructure": "Infrastruttura DDD", + "DomainDrivenDesignInfrastructure": "Infrastruttura di progettazione basata sul dominio", + "AutoRESTAPIs": "API REST automatiche", + "DynamicClientProxies": "Proxy client dinamici", + "DistributedEventBus": "Bus di eventi distribuito", + "DistributedEventBusWithRabbitMQIntegration": "Bus di eventi distribuito con integrazione RabbitMQ", + "TestInfrastructure": "Infrastruttura di test", + "AuditLoggingEntityHistories": "Registrazione di audit e cronologie delle entità", + "ObjectToObjectMapping": "Mappatura da oggetto a oggetto", + "ObjectToObjectMappingExplanation": "Astrazione della mappatura da oggetto a oggetto con integrazione AutoMapper.", + "EmailSMSAbstractions": "Astrazioni tramite e-mail e SMS", + "EmailSMSAbstractionsWithTemplatingSupport": "Astrazioni tramite posta elettronica e SMS con supporto per i modelli", + "Localization": "Localizzazione", + "SettingManagement": "Gestione delle impostazioni", + "ExtensionMethods": "Metodi di estensione", + "ExtensionMethodsHelpers": "Metodi di estensione e aiutanti", + "AspectOrientedProgramming": "Programmazione orientata agli aspetti", + "DependencyInjection": "Iniezione di dipendenza", + "DependencyInjectionByConventions": "Inserimento delle dipendenze mediante convenzioni", + "ABPCLIExplanation": "ABP CLI (Command Line Interface) è uno strumento a riga di comando per eseguire alcune operazioni comuni per soluzioni basate su ABP.", + "ModularityExplanation": "ABP fornisce un'infrastruttura completa per creare i propri moduli applicativi che possono avere entità, servizi, integrazione di database, API, componenti dell'interfaccia utente e così via.", + "MultiTenancyExplanation": "Il framework ABP non solo supporta lo sviluppo di applicazioni multi-tenant, ma rende anche il tuo codice per lo più inconsapevole del multi-tenancy.", + "MultiTenancyExplanation2": "Può determinare automaticamente l'inquilino corrente, isolare i dati di diversi inquilini l'uno dall'altro.", + "MultiTenancyExplanation3": "Supporta database singolo, database per tenant e approcci ibridi.", + "MultiTenancyExplanation4": "Ti concentri sul tuo codice aziendale e lasci che il framework gestisca il multi-tenancy per tuo conto.", + "BootstrapTagHelpersExplanation": "Invece di scrivere manualmente i dettagli ripetuti dei componenti bootstrap, usa gli helper tag di ABP per semplificarlo e sfruttare intellisense. Puoi sicuramente usare Bootstrap ogni volta che ne hai bisogno.", + "DynamicFormsExplanation": "Gli helper dei moduli dinamici e dei tag di input possono creare il modulo completo da una classe C # come modello.", + "AuthenticationAuthorizationExplanation": "Ricche opzioni di autenticazione e autorizzazione integrate in ASP.NET Core Identity & IdentityServer4. Fornisce un sistema di autorizzazione estensibile e dettagliato.", + "CrossCuttingConcernsExplanation": "Non ripetere te stesso per implementare tutte queste cose comuni ancora e ancora. Concentrati sul tuo codice aziendale e lascia che ABP li automatizzi secondo le convenzioni.", + "DatabaseConnectionTransactionManagement": "Connessione al database e gestione delle transazioni", + "CorrelationIdTracking": "Monitoraggio dell'ID di correlazione", + "BundlingMinificationExplanation": "ABP offre un sistema di raggruppamento e minimizzazione semplice, dinamico, potente, modulare e integrato.", + "VirtualFileSystemnExplanation": "Il Virtual File System consente di gestire file che non esistono fisicamente nel file system (disco). Viene utilizzato principalmente per incorporare file (js, css, immagine, cshtml ...) negli assembly e utilizzarli come file fisici in runtime.", + "ThemingExplanation": "Il sistema di temi consente di sviluppare applicazioni e moduli indipendentemente dal tema definendo un set di librerie e layout di base comuni, basati sul più recente framework Bootstrap.", + "DomainDrivenDesignInfrastructureExplanation": "Un'infrastruttura completa per creare applicazioni a più livelli basate sui modelli e sui principi di Domain Driven Design;", + "Specification": "Specifica", + "Repository": "Repository", + "DomainService": "Servizio di dominio", + "ValueObject": "Oggetto valore", + "ApplicationService": "Servizio applicazioni", + "DataTransferObject": "Oggetto trasferimento dati", + "AggregateRootEntity": "Radice aggregata, entità", + "AutoRESTAPIsExplanation": "ABP può configurare automaticamente i servizi dell'applicazione come controller API per convenzione.", + "DynamicClientProxiesExplanation": "Utilizza facilmente le tue API da client JavaScript e C #.", + "DistributedEventBusWithRabbitMQIntegrationExplanation": "Pubblica e utilizza facilmente eventi distribuiti utilizzando Distributed Event Bus integrato con integrazione RabbitMQ disponibile.", + "TestInfrastructureExplanation": "Il framework è stato sviluppato in mente per test di unità e integrazione. Fornisce classi di base per renderlo più facile. I modelli di avvio vengono forniti preconfigurati per i test.", + "AuditLoggingEntityHistoriesExplanation": "Registrazione di audit integrata per applicazioni business-critical. Richiesta, servizio, registrazione di controllo a livello di metodo e cronologie di entità con dettagli a livello di proprietà.", + "EmailSMSAbstractionsWithTemplatingSupportExplanation": "Le astrazioni di IEmailSender e ISmsSender separano la logica dell'applicazione dall'infrastruttura. Il sistema avanzato di modelli di posta elettronica consente di creare e localizzare modelli di posta elettronica e di utilizzarli facilmente quando necessario.", + "LocalizationExplanation": "Il sistema di localizzazione consente di creare risorse in semplici file JSON e utilizzarli per localizzare la tua interfaccia utente. Supporta scenari avanzati come ereditarietà, estensioni e integrazione JavaScript mentre è completamente compatibile con il sistema di localizzazione di AspNet Core.", + "SettingManagementExplanation": "Definisci le impostazioni per la tua applicazione e ottieni i valori in fase di esecuzione in base alla configurazione, al tenant e all'utente correnti.", + "ExtensionMethodsHelpersExplanation": "Non ripeterti nemmeno per parti di codice banali. Le estensioni e gli helper per i tipi standard rendono il codice molto più pulito e facile da scrivere.", + "AspectOrientedProgrammingExplanation": "Fornisce una comoda infrastruttura per creare proxy dinamici e implementare la programmazione orientata agli aspetti. Intercetta qualsiasi classe ed esegui il codice prima e dopo l'esecuzione di ogni metodo.", + "DependencyInjectionByConventionsExplanation": "Non è necessario registrare manualmente le classi per l'inserimento delle dipendenze. Registra automaticamente i tipi di servizio comuni per convenzione. Per altri tipi di servizi, puoi utilizzare interfacce e attributi per renderlo più semplice e sul posto.", + "DataFilteringExplanation": "Definisci e utilizza i filtri di dati che vengono applicati automaticamente quando esegui query sulle entità dal database. Quando si implementano interfacce semplici, vengono forniti filtri Soft Delete e MultiTenant.", + "PublishEvents": "Pubblica eventi", + "HandleEvents": "Gestisci eventi", + "AndMore": "e altro ancora ...", + "Code": "Codice", + "Result": "Risultato", + "SeeTheDocumentForMoreInformation": "Consulta il {0} documento per ulteriori informazioni", + "IndexPageHeroSection": " open source Framework
applicazione web
per asp.net core ", + "UiFramework": "Framework dell'interfaccia utente", + "EmailAddress": "Indirizzo e-mail", + "Mobile": "Mobile", + "ReactNative": "React Native", + "Strong": "Forte", + "Complete": "Completare", + "BasedLayeringModel": "Modello di stratificazione basato", + "Microservice": "Microservizio", + "Compatible": "Compatibile", + "MeeTTheABPCommunityInfo": "La nostra missione è creare un ambiente in cui gli sviluppatori possano aiutarsi a vicenda con articoli, tutorial, casi di studio, ecc. E incontrare persone che la pensano allo stesso modo.", + "JoinTheABPCommunityInfo": "Fatti coinvolgere da una vivace comunità e diventa un collaboratore di ABP Framework!", + "AllArticles": "Tutti gli articoli", + "SubmitYourArticle": "Invia il tuo articolo", + "DynamicClientProxyDocument": "Consulta la documentazione relativa al proxy del client dinamico per JavaScript e C # .", + "EmailSMSAbstractionsDocument": "Per ulteriori informazioni, consulta i documenti di invio di email e invio di SMS .", + "CreateProjectWizard": "Questa procedura guidata crea un nuovo progetto dal modello di avvio che è configurato correttamente per avviare rapidamente il progetto.", + "TieredOption": "Crea una soluzione a più livelli in cui i livelli API Web e Http sono fisicamente separati. Se non selezionata, crea una soluzione a più livelli meno complessa e adatta alla maggior parte degli scenari.", + "SeparateIdentityServerOption": "Separa il lato server in due applicazioni: la prima è per il server di identità e la seconda è per l'API HTTP lato server.", + "UseslatestPreVersion": "Utilizza l'ultima versione pre-rilascio", + "ReadTheDocumentation": " Leggi La documentazione ", + "Documentation": "Documentazione", + "GettingStartedTutorial": "Tutorial introduttivo", + "ApplicationDevelopmentTutorial": "Tutorial sullo sviluppo di applicazioni", + "TheStartupTemplate": "Il modello di avvio", + "InstallABPCLIInfo": "ABP CLI è il modo più veloce per avviare una nuova soluzione con il framework ABP. Installa ABP CLI utilizzando una finestra della riga di comando:", + "DifferentLevelOfNamespaces": "È possibile utilizzare diversi livelli di spazi dei nomi; per esempio. BookStore, Acme.BookStore o Acme.Retail.BookStore.", + "ABPCLIExamplesInfo": "Il comando nuovo crea un ' applicazione MVC a più livelli con Entity Framework Core come provider di database. Tuttavia, ha opzioni aggiuntive. Esempi:", + "SeeCliDocumentForMoreInformation": "Consulta il documento ABP CLI per ulteriori opzioni o seleziona la scheda \"Download diretto\" in alto.", + "Optional": "Opzionale", + "LocalFrameworkRef": "Mantieni il riferimento al progetto locale per i pacchetti del framework.", + "BlobStoring": "Archiviazione BLOB", + "BlobStoringExplanation": "Il sistema di archiviazione BLOB fornisce un'astrazione per lavorare con i BLOB. ABP fornisce alcune integrazioni di provider di archiviazione predefinite (Azure, AWS, File System, Database e così via) che puoi facilmente utilizzare nelle tue applicazioni.", + "TextTemplating": "Modelli di testo", + "TextTemplatingExplanation": "La creazione di modelli di testo viene utilizzata per eseguire il rendering dinamico dei contenuti in base a un modello e un modello (un oggetto dati). Ad esempio, puoi utilizzarlo per creare contenuti di posta elettronica dinamici con un modello predefinito.", + "MultipleUIOptions": "Molteplici opzioni di interfaccia utente", + "MultipleDBOptions": "Più fornitori di database", + "MultipleUIOptionsExplanation": "Il framework principale è progettato come indipendente dall'interfaccia utente e può funzionare con qualsiasi tipo di sistema di interfaccia utente, mentre sono disponibili più opzioni predefinite e integrate.", + "MultipleDBOptionsExplanation": "Il framework può funzionare con qualsiasi fonte di dati, mentre i seguenti provider sono ufficialmente sviluppati e supportati;", + "SelectLanguage": "Seleziona la lingua", + "LatestArticleOnCommunity": "Ultimo articolo sulla comunità ABP", + "Register": "Registrati", + "IsDownloadable": "È scaricabile" + } +} \ No newline at end of file diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/tr.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/tr.json index ef4ecbdcac..0da4a44beb 100644 --- a/abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/tr.json +++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/tr.json @@ -157,6 +157,41 @@ "EmailAddress": "E-Posta Adresi", "Mobile": "Mobil", "ReactNative": "React Native", - "SelectLanguage": "Dil seçin" + "SelectLanguage": "Dil seçin", + "Register": "Kayıt ol", + "IsDownloadable": "Yüklenebilir mi", + "DatabaseOptions": "Veritabanı Seçenekleri", + "BackToPackagesPage": "Paketler sayfasına geri dön", + "HowToInstall": "Nasıl Indirilir", + "SeeOnNpm": "NPM'de görüntüle", + "SeeOnNuget": "Nuget'de görüntüle", + "MVCGulpCommandExplanation": "Arayüz uygulaması olarak MVC (Razor Page) kullanıyorsanız, paketlerin indirilmesinden sonra \"gulp\" komutunu çalıştırın.", + "UsingABPCLI": "ABP CLI Kullanımı", + "WithoutABPCLI": "ABP CLI kullanmadan", + "ABPCLIModuleDependency": "ABP CLI otomatik olarak modül bağımlılıklarını ekler.", + "AddModuleDependency": "Modül bağımlılıklarını ekleyin", + "Packages": "Paketler", + "NugetPackages": "Nuget Paketleri", + "NPMPackages": "NPM Paketleri", + "SeeDocs": "Dökümanı Görüntüle", + "None": "Hiç", + "Application": "Uygulama", + "Module": "Modül", + "PackageName": "Paket adı", + "LicenseURL": "Lisans Linki", + "License": "Lisans", + "ProjectCreationSuccessMessage": "Projeniz başarıyla oluşturulmuştur", + "HowToRunSolution": "Uygulamayı Nasıl Çalıştırabiliriz?", + "GettingStartedMessage": "Uygulamanızı nasıl yapılandıracağınızı ve çalıştıracağınızı öğrenmek için başlanıç dökümanına bakınız.", + "WebAppDevTutorial": "Web Uygulaması Geliştirme Öğreticisi", + "WebAppDevTutorialMessage": "Adım adım web uygulaması geliştirme örneği için web uygulaması geliştirme öğreticisine bakınız.", + "CommunityArticles": "Topluluk Makaleleri", + "CommunityArticleMessage": "ABP Framework ile ilgili yararlı makaleleri okumak için ABP Topluluk Platformu'na bakın.", + "InvestigateSolutionDetails": "Çözüm detaylarını inceleyin", + "StartupTemplateDocumentationMessage": "Çözümünüzün mimarisini ve yapısını öğrenmek için uygulama başlangıç şablonu belgesine bakın.", + "ClientSideDevelopment": "İstemci Tarafı Geliştirme", + "ClientSideDevelopmentDocumentationMessage": "Kullanıcı arayüzü (istemci tarafı) geliştirmeyle ilgili temel noktaları öğrenmek için {0} belgesine bakın.", + "DatabaseProviderDocumentationMessage": "Veritabanı katmanı geliştirmeyle ilgili temel noktaları öğrenmek için {0} belgesine bakın.", + "ABPCommercialExplanationMessage": "ABP Commercial, ABP Framework için premium modüller, temalar, araçlar ve destek sağlar." } } \ No newline at end of file diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/zh-Hans.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/zh-Hans.json index 8185ead8cd..27505e138c 100644 --- a/abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/zh-Hans.json +++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/zh-Hans.json @@ -196,6 +196,39 @@ "MultipleDBOptionsExplanation": "该框架可以使用任何数据源,并且以下提供程序已得到正式开发和支持;", "SelectLanguage": "选择语言", "LatestArticleOnCommunity": "关于ABP社区的最新文章", - "Register": "寄存器" + "Register": "注册", + "DatabaseOptions": "数据库选项", + "BackToPackagesPage": "回到包页面", + "HowToInstall": "如何安装", + "SeeOnNpm": "在NPM查看", + "SeeOnNuget": "在Nuget查看", + "MVCGulpCommandExplanation": "如果你使用MVC (Razor Pages) UI,在包安装完成后运行 \"gulp\" 命令.", + "UsingABPCLI": "使用 Abp CLI", + "WithoutABPCLI": "不使用 ABP CLI", + "ABPCLIModuleDependency": "ABP CLI会自动添加模块依赖.", + "AddModuleDependency": "然后添加模块依赖", + "Packages": "包", + "NugetPackages": "Nuget包", + "NPMPackages": "NPM包", + "SeeDocs": "查看文档", + "None": "空", + "Application": "应用程序", + "Module": "模块", + "PackageName": "包名称", + "LicenseURL": "许可URL", + "License": "许可", + "ProjectCreationSuccessMessage": "你的项目创建成功", + "HowToRunSolution": "如何运行你的解决方案n?", + "GettingStartedMessage": "查看入门文档了解如何配置和运行你的解决方案.", + "WebAppDevTutorial": "Web App 开发教程", + "WebAppDevTutorialMessage": "查看web应用程序开发教程文档,一步一步的开发示例.", + "CommunityArticles": "社区文档", + "CommunityArticleMessage": "查看ABP社区平台来阅读关于ABP框架的文档.", + "InvestigateSolutionDetails": "调查解决方案细节", + "StartupTemplateDocumentationMessage": "查看应用程序启动模板文档来学习你的解决方案架构和结构.", + "ClientSideDevelopment": "客户端部分开发", + "ClientSideDevelopmentDocumentationMessage": "查看{0}文档来学习用户页面(客户端部分)开发.", + "DatabaseProviderDocumentationMessage": "查看{0}文档来学习用数据库层开发.", + "ABPCommercialExplanationMessage": "ABP商业版为ABP框架提供了高级模块,主题,工具和支持." } } \ No newline at end of file diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/zh-Hant.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/zh-Hant.json index 37f6747ea0..635abfc2fb 100644 --- a/abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/zh-Hant.json +++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/zh-Hant.json @@ -155,6 +155,41 @@ "IndexPageHeroSection": "asp.net core的開源Web應用程式
框架
", "UiFramework": "UI框架", "EmailAddress": "電子信箱地址", - "SelectLanguage": "选择语言" + "SelectLanguage": "选择语言", + "LatestArticleOnCommunity": "關於ABP社區的最新文章", + "Register": "註冊", + "DatabaseOptions": "數據庫選項", + "BackToPackagesPage": "回到包頁面", + "HowToInstall": "如何安裝", + "SeeOnNpm": "在NPM查看", + "SeeOnNuget": "在Nuget查看", + "MVCGulpCommandExplanation": "如果你使用MVC (Razor Pages) UI,在包安裝完成後運行 \"gulp\" 命令.", + "UsingABPCLI": "使用 Abp CLI", + "WithoutABPCLI": "不使用 ABP CLI", + "ABPCLIModuleDependency": "ABP CLI會自動添加模塊依賴.", + "AddModuleDependency": "然後添加模塊依賴", + "Packages": "包", + "NugetPackages": "Nuget包", + "NPMPackages": "NPM包", + "SeeDocs": "查看文檔", + "None": "空", + "Application": "應用程序", + "Module": "模塊", + "PackageName": "包名稱", + "LicenseURL": "許可URL", + "License": "許可", + "ProjectCreationSuccessMessage": "你的項目創建成功", + "HowToRunSolution": "如何運行你的解決方案?", + "GettingStartedMessage": "查看入門文檔了解如何配置和運行你的解決方案.", + "WebAppDevTutorial": "Web App 開發教程", + "WebAppDevTutorialMessage": "查看web應用程序開發教程文檔,一步一步的開發示例.", + "CommunityArticles": "社區文檔", + "CommunityArticleMessage": "查看ABP社區平臺來閱讀關於ABP框架的文檔.", + "InvestigateSolutionDetails": "調查解決方案細節", + "StartupTemplateDocumentationMessage": "查看應用程序啟動模板文檔來學習你的解決方案架構和結構.", + "ClientSideDevelopment": "客戶端部分開發", + "ClientSideDevelopmentDocumentationMessage": "查看{0}文檔來學習用戶頁面(客戶端部分)開發.", + "DatabaseProviderDocumentationMessage": "查看{0}文檔來學習用數據庫層開發.", + "ABPCommercialExplanationMessage": "ABP商業版為ABP框架提供了高級模塊,主題,工具和支持." } } \ No newline at end of file diff --git a/docs/en/Authorization.md b/docs/en/Authorization.md index 2632f3c88a..6b906fe194 100644 --- a/docs/en/Authorization.md +++ b/docs/en/Authorization.md @@ -265,37 +265,7 @@ myGroup.AddPermission("Book_Creation") #### Creating a Custom Permission Dependency -Any class implements the `IPermissionStateProvider` interface can disable a permission based on a custom condition. - -**Example:** - -````csharp -public class MyCustomPermissionStateProvider : IPermissionStateProvider -{ - public Task IsEnabledAsync(PermissionStateContext context) - { - // You can implement your own logic here. - return Task.FromResult( - context.Permission.Name.StartsWith("Acme.BookStore")); - } -} -```` - -Then you can add `MyCustomPermissionStateProvider` to any permission definition, using the `AddStateProviders` extension method: - -````csharp -myGroup.AddPermission("Book_Creation") - .AddStateProviders(new MyCustomPermissionStateProvider()); -```` - -Or you can globally add your custom provider to make it working for all permissions: - -````csharp -Configure(options => -{ - options.GlobalStateProviders.Add(); -}); -```` +`PermissionDefinition` supports state check, Please refer to [Simple State Checker's documentation](SimpleStateChecker.md) ## IAuthorizationService @@ -473,7 +443,7 @@ public class SocialSecurityNumberClaimsPrincipalContributor : IAbpClaimsPrincipa var socialSecurityNumber = await userService.GetSocialSecurityNumberAsync(userId.Value); if (socialSecurityNumber != null) { - identity.AddOrReplace(new Claim("SocialSecurityNumber", socialSecurityNumber)); + identity.AddClaim(new Claim("SocialSecurityNumber", socialSecurityNumber)); } } } @@ -484,4 +454,4 @@ public class SocialSecurityNumberClaimsPrincipalContributor : IAbpClaimsPrincipa * [Permission Management Module](Modules/Permission-Management.md) * [ASP.NET Core MVC / Razor Pages JavaScript Auth API](UI/AspNetCore/JavaScript-API/Auth.md) -* [Permission Management in Angular UI](UI/Angular/Permission-Management.md) \ No newline at end of file +* [Permission Management in Angular UI](UI/Angular/Permission-Management.md) diff --git a/docs/en/Blog-Posts/2021-04-05 CmsKit/POST.md b/docs/en/Blog-Posts/2021-04-05 CmsKit/POST.md index ad8b89faa0..740adb96c7 100644 --- a/docs/en/Blog-Posts/2021-04-05 CmsKit/POST.md +++ b/docs/en/Blog-Posts/2021-04-05 CmsKit/POST.md @@ -1,3 +1,85 @@ -# Introducing the CMS Kit Module for the ABP Framework +# Introducing The CMS-Kit Module + +One of the most exciting announcements of the ABP Framework 4.3 release was releasing the initial version of the CMS Kit module. The team had been working hard to release the initial version for months. For those who didn't read the [ABP Framework 4.3 release post](https://blog.abp.io/abp/ABP-Framework-4.3-RC-Has-Been-Published), the CMS Kit module adds CMS(Content Management System) capabilities to your application. Some of the CMS Kit features are open source and free, while others are only included in the Pro version included in the ABP Commercial. + +List of free and pro features in the CMS Kit module; + +- Free + - Page System: Provides a **page** management system to manage dynamic pages. + - Blog System: Provides a **blog** system to create blogs and publish posts. + - Tag System: Provides a **tag** system to tag any kind of resources, such as blog posts. + - Comment System: Provides a **comment** system to add comments feature to any type of resource, such as blog posts, products, etc. + - Reaction System: Provides a **reaction** system to add reactions to any type of resource, such as blog posts or comments, etc. + - Rating System: Provides a **rating** system to add ratings feature to any type of resource, such as comments, products, etc. +- Pro + - Newsletter System: Provides a **newsletter** system to allow users to subscribe to newsletters. + - Contact Form System: Provides a **contact form** system to allow users to write a message to you on public websites. + +## Installation + +CMS Kit module comes installed with commercial templates when you create the solution with the public website option. You can run the following command and create a solution with a public website. + +```bash +abp new Acme --with-public-website +``` + +If you're using the open-source version or adding the module to an existing project, the ABP CLI allows adding a module to a solution using `add-module` command. + +You can run the following command to add the module to an open-source solution. + +```bash +abp add-module Volo.CmsKit +``` + +If you're a commercial user, run the following command to install the pro version of the module. + +```bash +abp add-module Volo.CmsKit.Pro +``` + +After adding the module to the solution, you need to configure features. The CMS Kit module uses the [global feature](https://docs.abp.io/en/abp/latest/Global-Features) system for all features. To enable the features in the CMS Kit module, open the `GlobalFeatureConfigurator` class in the `Domain.Shared` project and place the following code to the `Configure` method to enable all features in the CMS kit module. + + ```csharp +GlobalFeatureManager.Instance.Modules.CmsKit(cmsKit => +{ + cmsKit.EnableAll(); +}); + ``` + +If you're a commercial user, you need to enable CMS Kit Pro features as well. + +```csharp +GlobalFeatureManager.Instance.Modules.CmsKitPro(cmsKitPro => +{ + cmsKitPro.EnableAll(); +}); +``` + +> If you are using Entity Framework Core, do not forget to add a new migration and update your database after configuring the features. + +We've completed the installation step. Run the project, and you will see the CMS menu item in the menu. + +![cms-kit-menu](cms-kit-menu.png) + +> CMS Kit's initial release only supports the MVC UI. We're planning to add Angular and Blazor support in upcoming releases. + +## Package Structures + +CMS Kit is designed for various usage scenarios. When you visit [nuget.org](https://www.nuget.org/packages?q=Volo.CmsKit) or [abp.io](https://abp.io/packages?moduleName=Volo.CmsKit.Pro) to see the available CMS Kit packages, you will find out that packages have admin, public and unified versions. + +For example, + + - `Volo.CmsKit.Admin.Application`: Contains functionality required by admin websites. + - `Volo.CmsKit.Public.Application`: Contains functionality required by public websites. + - `Volo.CmsKit.Application` : Unified package dependent on both public and admin packages. + + If you want to separate admin and public website codes, you can use the admin and public packages. However, if you want to keep admin and public website codes in a shared project, you can use the unified packages to include admin and public packages. + +> It is recommended to use the unified packages instead of adding both admin and public packages. + + + +We've covered the initial features, installation and configuration steps in this post. You can read the [open-source](https://docs.abp.io/en/abp/latest/Modules/Cms-Kit) and [commercial](https://docs.abp.io/en/commercial/latest/modules/CMS-Kit) documentation to get further information about features and the CMS Kit module. CMS Kit's initial version contains lots of features that you can easily integrate and use in your applications. We're planning to improve the existing features, fixing bugs and adding new features in upcoming releases. If you want to give some feedback or have a feature request, please reach out to us from [GitHub](https://github.com/abpframework/abp) or [support.abp.io](https://support.abp.io). We will be happy to plan the CMS Kit module's future together. + +Thank you! -TODO... \ No newline at end of file diff --git a/docs/en/Blog-Posts/2021-04-05 CmsKit/cms-kit-menu.png b/docs/en/Blog-Posts/2021-04-05 CmsKit/cms-kit-menu.png new file mode 100644 index 0000000000..3f187c9a9d Binary files /dev/null and b/docs/en/Blog-Posts/2021-04-05 CmsKit/cms-kit-menu.png differ diff --git a/docs/en/Community-Articles/2021-03-12-Simple-SignalR-Notification/POST.md b/docs/en/Community-Articles/2021-03-12-Simple-SignalR-Notification/POST.md index 7a88adde44..8aeff16612 100644 --- a/docs/en/Community-Articles/2021-03-12-Simple-SignalR-Notification/POST.md +++ b/docs/en/Community-Articles/2021-03-12-Simple-SignalR-Notification/POST.md @@ -38,8 +38,19 @@ Open `YourProjectWebModule.cs` class and add the following line to the `PreConfi #### 2- Add Client Scripts -2- In the `ConfigureServices` method of your web module add the following code to add the `signalr.js` and `notification-hub.js`. We'll add these packages in the next steps. +2- In the `ConfigureServices` method of your web module add the following code to add the `signalr.js` and `notification-hub.js`. We'll add these packages in the next steps. If you are not using Lepton Theme you can add the files to `StandardBundles.Scripts.Global`. +```csharp + Configure(options => + { + options + .ScriptBundles + .Get(LeptonThemeBundles.Scripts.Global) //or -> Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Bundling.StandardBundles.Scripts.Global + .AddFiles("/libs/signalr/signalr.js") + .AddFiles("/Pages/notification-hub.js"); + }); + ``` + ![Script Bundles](add-script-bundles.jpg) #### 3- Add Hub Endpoint @@ -71,6 +82,11 @@ Add the following JavaScript class into your `Pages` folder in your Web project. Add [Microsoft.SignalR](https://www.npmjs.com/package/@microsoft/signalr) JavaScript package to the `package.json` which is located in your root folder of the Web project. After you add it, run `yarn` command in your Web directory to be able to install this package. +You can install the latest version (3.1.13 will be old) +``` + "@microsoft/signalr": "^3.1.13" +```` + ![Add SignalR package](signalr-package.jpg) #### 3- Add resource Mapping @@ -94,6 +110,8 @@ To do this replace the `Index.cshtml` and `Index.cshtml.cs` with the followings: #### 5- See it in action -Run your web project and in the Index page you'll see a button named as "Get Notification". Click the button and see the notification that comes from SignalR. This is a basic usage of SignalR notification system. You can implement it according to your own requirements. +Run your web project and in the Index page you'll Server Time will be updated every second. The time information comes from backend via SignalR. +This is a very basic usage of SignalR notification system. +You can implement your own SignalR notification system based on your requirements. ![Result](result.jpg) diff --git a/docs/en/Entity-Framework-Core-Migrations.md b/docs/en/Entity-Framework-Core-Migrations.md index be5968a9af..4d42d8bb97 100644 --- a/docs/en/Entity-Framework-Core-Migrations.md +++ b/docs/en/Entity-Framework-Core-Migrations.md @@ -881,6 +881,67 @@ We had a reference to the `Acme.BookStore.EntityFrameworkCore.DbMigrationsForSec You can run the `.DbMigrator` application to migrate & seed the databases. To test, you can delete both databases and run the `.DbMigrator` application again to see if it creates both of the databases. +## Separating Host & Tenant Database Schemas + +In a multi-tenant solution, you may want to separate your database schemas, so host-related tables don't locate in the tenant databases when tenants have separate databases. + +Some pre-built ABP modules are related only with the host side, like the [Tenant Management](Modules/Tenant-Management.md) module. So, in the tenant `DbContext` class you don't call `modelBuilder.ConfigureTenantManagement()` and that's all. + +However, some modules, like the [Identity](Modules/Identity.md) module, is both used in host and tenant sides. It stores tenant users in the tenant database and host users in the host database. However, it stores some entities, like `IdentityClaimType`, only in the host side. In this case, you don't want to add these tables in the tenant database, even if they are not used and will always be empty. + +ABP provides a simple way to set the multi-tenancy side for a `DbContext`, so the modules can check it and decide to map tables to the database, or not. + +````csharp +public class MyTenantDbContext : AbpDbContext +{ + protected override void OnModelCreating(ModelBuilder modelBuilder) + { + modelBuilder.SetMultiTenancySide(MultiTenancySides.Tenant); + + base.OnModelCreating(modelBuilder); + modelBuilder.ConfigureIdentity(); + modelBuilder.ConfigureFeatureManagement(); + modelBuilder.ConfigureAuditLogging(); + } +} +```` + +The first line in the `OnModelCreating` sets multi-tenancy side to `Tenant`. For this example, Feature management tables are not created (because all the tables are host-specific), so calling `modelBuilder.ConfigureFeatureManagement()` has no effect. Also, `ConfigureIdentity()` call respects to the multi-tenancy side and doesn't create host-specific tables for this database. + +`SetMultiTenancySide` can get the following values: + +* `MultiTenancySides.Both` (**default value**): This `DbContext` (and the related database) is shared by host and tenant. +* `MultiTenancySides.Host`: This `DbContext` (and the related database) is used only by the host side. +* `MultiTenancySides.Tenant`: This `DbContext` (and the related database) is only for tenants. + +If you create a re-usable application module or want to check that value in your application code, you can use `modelBuilder.GetMultiTenancySide()` to check the current side. + +````csharp +var side = modelBuilder.GetMultiTenancySide(); +if (!side.HasFlag(MultiTenancySides.Host)) +{ + ... +} +```` + +Or practically you can use one of the shortcut extension methods: + +````csharp +if (modelBuilder.IsTenantOnlyDatabase()) +{ + ... +} +```` + +There are four methods to check the current side: + +* `IsHostDatabase()`: Returns `true` if you should create host-related tables. It is equivalent of checking `modelBuilder.GetMultiTenancySide().HasFlag(MultiTenancySides.Host)`. +* `IsHostOnlyDatabase()`: Returns `true` if you should only create host-related tables, but should not create tenant-related tables. It is equivalent of checking `modelBuilder.GetMultiTenancySide() == MultiTenancySides.Host`. +* `IsTenantDatabase()`: Returns `true` if you should create tenant-related tables. It is equivalent of checking `modelBuilder.GetMultiTenancySide().HasFlag(MultiTenancySides.Tenant)`. +* `IsTenantOnlyDatabase()`: Returns `true` if you should only create tenant-related tables, but should not create host-related tables. It is equivalent of checking `modelBuilder.GetMultiTenancySide() == MultiTenancySides.Tenant`. + +All pre-built ABP [modules](Modules/Index.md) checks this value in their `modelBuilder.ConfigureXXX()` methods. + ## Conclusion This document explains how to split your databases and manage your database migrations of your solution for Entity Framework Core. In brief, you need to have a separate migration project per different databases. diff --git a/docs/en/Entity-Framework-Core.md b/docs/en/Entity-Framework-Core.md index a2c0e79996..fcbf5d8091 100644 --- a/docs/en/Entity-Framework-Core.md +++ b/docs/en/Entity-Framework-Core.md @@ -626,6 +626,24 @@ See the "*ConfigureByConvention Method*" section above for more information. ## Advanced Topics +### Controlling the Multi-Tenancy + +If your solution is [multi-tenant](Multi-Tenancy.md), tenants may have **separate databases**, you have **multiple** `DbContext` classes in your solution and some of your `DbContext` classes should be usable **only from the host side**, it is suggested to add `[IgnoreMultiTenancy]` attribute on your `DbContext` class. In this case, ABP guarantees that the related `DbContext` always uses the host [connection string](Connection-Strings.md), even if you are in a tenant context. + +**Example:** + +````csharp +[IgnoreMultiTenancy] +public class MyDbContext : AbpDbContext +{ + ... +} +```` + +Do not use the `[IgnoreMultiTenancy]` attribute if any one of your entities in your `DbContext` can be persisted in a tenant database. + +> When you use repositories, ABP already uses the host database for the entities don't implement the `IMultiTenant` interface. So, most of time you don't need to `[IgnoreMultiTenancy]` attribute if you are using the repositories to work with the database. + ### Set Default Repository Classes Default generic repositories are implemented by `EfCoreRepository` class by default. You can create your own implementation and use it for all the default repository implementations. @@ -706,7 +724,19 @@ One advantage of using an interface for a DbContext is then it will be replaceab ### Replace Other DbContextes -Once you properly define and use an interface for DbContext, then any other implementation can replace it using the `ReplaceDbContext` option: +Once you properly define and use an interface for DbContext, then any other implementation can use the following ways to replace it: + +**ReplaceDbContextAttribute** + +```csharp +[ReplaceDbContext(typeof(IBookStoreDbContext))] +public class OtherDbContext : AbpDbContext, IBookStoreDbContext +{ + //... +} +``` + +**ReplaceDbContext option** ````csharp context.Services.AddAbpDbContext(options => @@ -782,4 +812,4 @@ public class MyCustomEfCoreBulkOperationProvider ## See Also * [Entities](Entities.md) -* [Repositories](Repositories.md) +* [Repositories](Repositories.md) \ No newline at end of file diff --git a/docs/en/Features.md b/docs/en/Features.md index b185eb2d74..3b1869a9a5 100644 --- a/docs/en/Features.md +++ b/docs/en/Features.md @@ -146,9 +146,9 @@ A feature should be defined to be able to check it. ### FeatureDefinitionProvider -Create a class inheriting the `FeatureDefinitionProvider` to define permissions. +Create a class inheriting the `FeatureDefinitionProvider` to define features. -**Example: Defining permissions** +**Example: Defining features** ```csharp using Volo.Abp.Features; diff --git a/docs/en/Modules/Cms-Kit.md b/docs/en/Modules/Cms-Kit.md index e13f1e585b..1259686f8e 100644 --- a/docs/en/Modules/Cms-Kit.md +++ b/docs/en/Modules/Cms-Kit.md @@ -1,3 +1,159 @@ # CMS Kit Module -TODO \ No newline at end of file +This module provides CMS(Content Management System) capabilities for your application. + +* Provides a **page** management system to manage dynamic pages. +* Provides a [**blog**](cms-kit/Blog-System.md) system to create blogs and publish posts. +* Provides a [**tag**](cms-kit/Tag-Management.md) system to tag any kind of resources, like blog posts. +* Provides a [**comment**](cms-kit/Comment-System.md) system to add comments feature to any kind of resource, like blog posts, products, etc. +* Provides a [**reaction**](cms-kit/Reaction-System.md) system to add reactions feature to any kind of resource, like blog posts or comments. +* Provides a [**rating**](cms-kit/Rating-System.md) system to add rating feature to any kind of resource. + +## How to install + +The ABP CLI allows adding a module to a solution using `add-module` command. CMS kit module can be added using the command below; + +```bash +abp add-module Volo.CmsKit +``` +Open the `GlobalFeatureConfigurator` class in the `Domain.Shared` project and place the following code to the `Configure` method to enable all features in the CMS kit module. + +```csharp +GlobalFeatureManager.Instance.Modules.CmsKit(cmsKit => +{ + cmsKit.EnableAll(); +}); + +``` + +> If you are using EntityFrameworkCore, do not forget to add a new migration and update your database. + +## Packages + +This module follows the [module development best practices guide](https://docs.abp.io/en/abp/latest/Best-Practices/Index) and consists of several NuGet and NPM packages. See the guide if you want to understand the packages and relations between them. + +CMS kit packages are designed for various usage scenarios. When you visit the [CMS kit package list page](https://www.nuget.org/packages?q=Volo.CmsKit), you will see that packages have admin, public and unified versions. +For example, + - `Volo.CmsKit.Admin.Application`: Contains functionality required by admin websites. + - `Volo.CmsKit.Public.Application`: Contains functionality required by public websites. + - `Volo.CmsKit.Application` : Unified package dependent on both public and admin packages. + +If you want to separate admin and public website codes, you can use the admin and public packages. However, if you want to keep admin and public website codes in a shared project, you can use the unified packages to include admin and public packages. + +It is recommended to use the unified packages instead of adding both admin and public packages. + +## Feature System + +CMS kit uses the [global feature](https://docs.abp.io/en/abp/latest/Global-Features) system for all implemented features. You can use the global feature system to enable all features or only enabled specific features easily. + +To enable all features in the CMS kit, open the `GlobalFeatureConfigurator` class in the `Domain.Shared` project. + +```csharp +GlobalFeatureManager.Instance.Modules.CmsKit(cmsKit => +{ + cmsKit.EnableAll(); +}); +``` + +You can only enable specific features such as pages, like below. + +```csharp +GlobalFeatureManager.Instance.Modules.CmsKit(cmsKit => +{ + cmsKit.Pages.Enable(); +}); +``` + +## User interface + +### Menu items + +CMS kit module adds the following items to the "Main" menu, under the "CMS" menu item: + +* **Pages**: Page management page. +* **Blogs**: Blog management page. +* **Blog Posts**: Blog post management page. +* **Tags**: Tag management page. +* **Comments**: Comment management page. + +`CmsKitAdminMenus` class has the constants for the menu item names. + +### Pages + +### Page Management + +Pages page is used to manage dynamic pages in the system. + +![pages-page](../images/cmskit-module-pages-page.png) + +You can create or edit an existing page on this page. + +![pages-edit](../images/cmskit-module-pages-edit.png) + +* When you create a page, you can access the created page via `pages/{slug}` URL. + +### Blog Management + +Blogs page is used to create and manage blogs in your system. + +![blogs-page](../images/cmskit-module-blogs-page.png) + +A screenshot from the new blog creation modal: + +![blogs-edit](../images/cmskit-module-blogs-edit.png) + +#### Blog Features + +You can enable or disable a specific feature for blogs by clicking the features action. + +![blogs-feature-action](../images/cmskit-module-blogs-feature-action.png) + +You can select/deselect the desired features for blog posts. + +![features-dialog](../images/cmskit-module-features-dialog.png) + +### Blog Post Management + +When you create blogs, you can manage blog posts on this page. + +![blog-posts-page](../images/cmskit-module-blog-posts-page.png) + +You can create and edit an existing blog post on this page. If you enable specific features such as tags, you can set tags for the blog post on this page. + +![blog-post-edit](../images/cmskit-module-blog-post-edit.png) + +### Tag Management + +CMS Kit provides an extensible tagging mechanism to add tagging capabilities to various places. + +![tags-page](../images/cmskit-module-tags-page.png) + +You can create or edit an existing tag on this page. + +![tag-edit](../images/cmskit-module-tag-edit.png) + +### Comment Management + +CMS Kit provides an extensible commenting mechanism to add comments to various places. You can add comment control to anywhere you want and manage the comments. + +You can view and manage comments on this page. + +![comment-page](../images/cmskit-module-comment-page.png) + +You can manage and view replies on this page. + +![comments-detail](../images/cmskit-module-comments-detail.png) + +### Reactions + +CMS Kit provides an extensible reaction component system to allow users to send reactions to your content. Here how the reactions component looks on a sample page. + +![reactions](../images/cmskit-module-reactions.png) + +You can also customize the reaction icons shown in the reaction component. + +### Ratings + +You can use the rating component to add rating a mechanism to your content. Here how the rating component looks on a sample page. + +![ratings](../images/cmskit-module-ratings.png) diff --git a/docs/en/Modules/cms-kit/Blog-System.md b/docs/en/Modules/cms-kit/Blog-System.md new file mode 100644 index 0000000000..6222064e67 --- /dev/null +++ b/docs/en/Modules/cms-kit/Blog-System.md @@ -0,0 +1,98 @@ +# Blog System + +CMS kit provides a **blog** system to add blogs & posts to a public website. This section describes the details of the blog system. + +## Feature + +CMS kit uses the [global feature](https://docs.abp.io/en/abp/latest/Global-Features) system for all implemented features. Commercial startup templates come with all the CMS Kit-related features are enabled by default, if you create the solution with the public website option. If you're installing the CMS Kit manually or want to enable the blog feature individually, open the `GlobalFeatureConfigurator` class in the `Domain.Shared` project and place the following code to the `Configure `method. + +```csharp +GlobalFeatureManager.Instance.Modules.CmsKit(cmsKit => +{ + cmsKit.Blogs.Enable(); +}); +``` + +# Internals + +## Domain Layer + +#### Aggregates + +This module follows the [Entity Best Practices & Conventions](https://docs.abp.io/en/abp/latest/Best-Practices/Entities) guide. + +- `Blog` _(aggregate root)_: Presents blogs of application. +- `BlogPost`_(aggregate root)_: Presents blog posts in blogs. +- `BlogFeature`:_(aggregate root)_: Presents blog features enabled/disabled state. Such as reactions, ratings, comments, etc. + +#### Repositories + +This module follows the [Repository Best Practices & Conventions](https://docs.abp.io/en/abp/latest/Best-Practices/Repositories) guide. + +Following custom repositories are defined for this feature: + +- `IBlogRepository` +- `IBlogPostRepository` +- `IBlogFeatureRepository` + +#### Domain services + +This module follows the [Domain Services Best Practices & Conventions](https://docs.abp.io/en/abp/latest/Best-Practices/Domain-Services) guide. + +- `BlogManager`: Includes some operations for `Blog` aggreate root to keep data consistency. + - `CreateAsync`: Creates a new `Blog` entity and makes sure slug is used one time. + - `UpdateAsync`: Updates existing `Blog` entity and makes sure slug is used one time. +- `BlogPostManager`: Includes some operations for `BlogPost` aggreagate root such as creating & updating. + - `CreateAsync`: Creates a new BlogPost and makes sure slug is used only one time. + - `SetSlugUrlAsync`: Sets `UrlSlug` property of BlogPost entity and makes sure slug isn't duplicated in same blog. +- `BlogFeatureManager`: Includes some operations for managing blog features. + - `SetAsync`: Sets a feature enabled/disabled for a Blog. + - `SetDefaultsAsync`: Resets all feature configuration for a Blog. + +### Application layer + +#### Application Services + +##### Admin + +- `BlogAdminAppService` _(implements `IBlogAdminAppService`)_: Implements use cases of blog management. +- `BlogFeatureAdminAppService` _(implements `IBlogFeatureAdminAppService`)_: Implements use cases of blog feature management. +- `BlogPostAdminAppService` _(implements `IBlogPostAdminAppService`)_: Implements use cases of blog post management. + +##### Common + +- `BlogFeatureAppService` _(implements I`BlogFeatureAppService`)_: Implements feature checking operations. + +##### Public + +- `BlogPostPublicAppService` _(implements `IBlogPostPublicAppService`)_: Implements use cases of blog posts management on public websites. + +### Database providers + +#### Common + +##### Table / collection prefix & schema + +All tables/collections use the `Cms` prefix by default. Set static properties on the `CmsKitDbProperties` class if you need to change the table prefix or set a schema name (if supported by your database provider). + +##### Connection string + +This module uses `CmsKit` for the connection string name. If you don't define a connection string with this name, it fallbacks to the `Default` connection string. + +See the [connection strings](https://docs.abp.io/en/abp/latest/Connection-Strings) documentation for details. + +#### Entity Framework Core + +##### Tables + +- CmsBlogs +- CmsBlogPosts +- CmsBlogFeatures + +#### MongoDB + +##### Collections + +- CmsBlogs +- CmsBlogPosts +- CmsBlogFeatures diff --git a/docs/en/Modules/cms-kit/Comment-System.md b/docs/en/Modules/cms-kit/Comment-System.md new file mode 100644 index 0000000000..542be54c59 --- /dev/null +++ b/docs/en/Modules/cms-kit/Comment-System.md @@ -0,0 +1,117 @@ +# Comment System + +CMS kit provides a **comment** system to add comments feature to any kind of resource, like blog posts, products, etc. This section describes the details of the comments system. + +## Feature + +CMS kit uses the [global feature](https://docs.abp.io/en/abp/latest/Global-Features) system for all implemented features. Commercial startup templates come with all the CMS kit related features are enabled by default, if you create the solution with public website option. If you're installing the CMS kit manually or want to enable the comment feature individually, open the `GlobalFeatureConfigurator` class in the `Domain.Shared` project and place the following code to the `Configure ` method. + +```csharp +GlobalFeatureManager.Instance.Modules.CmsKit(cmsKit => +{ + cmsKit.Comments.Enable(); +}); +``` + +# Options + +## CmsKitCommentOptions + +You can use the comment system to add comments to any kind of resources, like blog posts, products etc. Comment system provides a mechanism to group comment definitions by entity types. For example, if you want to use comment system for blog posts and products, you need to define two entity types named `BlogPosts` and `Product`, and add comments under these entity types. + +`CmsKitCommentOptions` can be configured in the domain layer, in the `ConfigureServices` method of your [module](https://docs.abp.io/en/abp/latest/Module-Development-Basics). Example: + +```csharp +Configure(options => +{ + options.EntityTypes.Add(new CommentEntityTypeDefinition("Product")); +}); +``` + +> If you're using the blog feature, the ABP framework defines an entity type for the blog feature automatically. You can easily override or remove the predefined entity types in `Configure` method like shown above. + +`CmsKitCommentOptions` properties: + +- `EntityTypes`: List of defined entity types(`CmsKitCommentOptions`) in the comment system. + +`CommentEntityTypeDefinition` properties: + +- `EntityType`: Name of the entity type. + +# Internals + +## Domain Layer + +#### Aggregates + +This module follows the [Entity Best Practices & Conventions](https://docs.abp.io/en/abp/latest/Best-Practices/Entities) guide. + +##### Comment + +A comment represents a written comment from a user. + +- `Comment` (aggregate root): Represents a written comment in the system. + +#### Repositories + +This module follows the [Repository Best Practices & Conventions](https://docs.abp.io/en/abp/latest/Best-Practices/Repositories) guide. + +Following custom repositories are defined for this feature: + +- `ICommentRepository` + +#### Domain services + +This module follows the [Domain Services Best Practices & Conventions](https://docs.abp.io/en/abp/latest/Best-Practices/Domain-Services) guide. + +##### Comment Manager + +`CommentManager` is used to perform some operations for the `Comment` aggregate root. + +### Application layer + +#### Application services + +- `CommentAdminAppService` (implements `ICommentAdminAppService`): Implements the use cases of comment management system, like listing or removing comments etc. +- `CommentPublicAppService` (implements `ICommentPublicAppService`): Implements the use cases of comment management on the public websites, like listing comments, adding comments etc. + +### Database providers + +#### Common + +##### Table / collection prefix & schema + +All tables/collections use the `Cms` prefix by default. Set static properties on the `CmsKitDbProperties` class if you need to change the table prefix or set a schema name (if supported by your database provider). + +##### Connection string + +This module uses `CmsKit` for the connection string name. If you don't define a connection string with this name, it fallbacks to the `Default` connection string. + +See the [connection strings](https://docs.abp.io/en/abp/latest/Connection-Strings) documentation for details. + +#### Entity Framework Core + +##### Tables + +- CmsComments + +#### MongoDB + +##### Collections + +- **CmsComments** + +### MVC UI + +The comment system provides a commenting widget to allow users to send comments to resources on public websites. You can simply place the widget on a page like below. + +```csharp +@await Component.InvokeAsync(typeof(CommentingViewComponent), new +{ + entityType = "entityType", + entityId = "entityId" +}) +``` +You need to specify entity type and entity ID parameters. Entity type represents the group name you specified while defining the comments in the domain module. Entity ID represents the unique identifier for the resource that users send comments to, such as blog post ID or product ID. + +For more information about widgets see [widgets](https://docs.abp.io/en/abp/latest/UI/AspNetCore/Widgets) documentation. diff --git a/docs/en/Modules/cms-kit/Rating-System.md b/docs/en/Modules/cms-kit/Rating-System.md new file mode 100644 index 0000000000..76aaaaa249 --- /dev/null +++ b/docs/en/Modules/cms-kit/Rating-System.md @@ -0,0 +1,116 @@ +# Rating System + +CMS kit provides a **rating** system to to add ratings feature to any kind of resource like blog posts, comments, etc. This section describes the details of the rating system. + +## Feature + +CMS kit uses the [global feature](https://docs.abp.io/en/abp/latest/Global-Features) system for all implemented features. Commercial startup templates come with all the CMS kit related features are enabled by default, if you create the solution with the public website option. If you're installing the CMS kit manually or want to enable the rating feature individually, open the `GlobalFeatureConfigurator` class in the `Domain.Shared` project and place the following code to the `Configure ` method. + +```csharp +GlobalFeatureManager.Instance.Modules.CmsKit(cmsKit => +{ + cmsKit.Ratings.Enable(); +}); +``` + +# Options + +## CmsKitRatingOptions + +You can use the rating system to to add ratings to any kind of resource, like blog posts, comments, etc. The rating system provides a mechanism to group ratings by entity types. For example, if you want to use the rating system for products, you need to define an entity type named `Product` and then add ratings under the defined entity type. + +`CmsKitRatingOptions` can be configured in the domain layer, in the `ConfigureServices` method of your [module](https://docs.abp.io/en/abp/latest/Module-Development-Basics). Example: + +```csharp +Configure(options => +{ + options.EntityTypes.Add(new RatingEntityTypeDefinition("Product")); +}); +``` + +> If you're using the blog feature, the ABP framework defines an entity type for the blog feature automatically. You can easily override or remove the predefined entity types in `Configure` method like shown above. + +`CmsKitRatingOptions` properties: + +- `EntityTypes`: List of defined entity types(`RatingEntityTypeDefinition`) in the rating system. + +`RatingEntityTypeDefinition` properties: + +- `EntityType`: Name of the entity type. + +# Internals + +## Domain Layer + +#### Aggregates + +This module follows the [Entity Best Practices & Conventions](https://docs.abp.io/en/abp/latest/Best-Practices/Entities) guide. + +##### Rating + +A rating represents a given rating from a user. + +- `Rating` (aggregate root): Represents a given rating in the system. + +#### Repositories + +This module follows the [Repository Best Practices & Conventions](https://docs.abp.io/en/abp/latest/Best-Practices/Repositories) guide. + +Following custom repositories are defined for this feature: + +- `IRatingRepository` + +#### Domain services + +This module follows the [Domain Services Best Practices & Conventions](https://docs.abp.io/en/abp/latest/Best-Practices/Domain-Services) guide. + +##### Reaction Manager + +`RatingManager` is used to perform some operations for the `Rating` aggregate root. + +### Application layer + +#### Application services + +- `RatingPublicAppService` (implements `IRatingPublicAppService`): Implements the use cases of rating system. + +### Database providers + +#### Common + +##### Table / collection prefix & schema + +All tables/collections use the `Cms` prefix by default. Set static properties on the `CmsKitDbProperties` class if you need to change the table prefix or set a schema name (if supported by your database provider). + +##### Connection string + +This module uses `CmsKit` for the connection string name. If you don't define a connection string with this name, it fallbacks to the `Default` connection string. + +See the [connection strings](https://docs.abp.io/en/abp/latest/Connection-Strings) documentation for details. + +#### Entity Framework Core + +##### Tables + +- CmsRatings + +#### MongoDB + +##### Collections + +- **CmsRatings** + +### MVC UI + +The ratings system provides a rating widget to allow users send ratings to resources in public websites. You can simply place the widget on a page like below. + +```csharp +@await Component.InvokeAsync(typeof(RatingViewComponent), new +{ + entityType = "entityType", + entityId = "entityId" +}) +``` +You need to specify entity type and entity ID parameters. Entity type represents the group name you specified while defining the reactions in the domain module. Entity ID represents the unique identifier for the resource that users give ratings to, such as blog post ID or product ID. + +For more information about widgets see [widgets](https://docs.abp.io/en/abp/latest/UI/AspNetCore/Widgets) documentation. \ No newline at end of file diff --git a/docs/en/Modules/cms-kit/Reaction-System.md b/docs/en/Modules/cms-kit/Reaction-System.md new file mode 100644 index 0000000000..e1219e24c3 --- /dev/null +++ b/docs/en/Modules/cms-kit/Reaction-System.md @@ -0,0 +1,128 @@ +# Reaction System + +CMS kit provides a **reaction** system to add reactions feature to any kind of resource, like blog posts or comments. This section describes the details of the reaction system. + +## Feature + +CMS kit uses the [global feature](https://docs.abp.io/en/abp/latest/Global-Features) system for all implemented features. Commercial startup templates come with all the CMS kit related features are enabled by default, if you create the solution with the public website option. If you're installing the CMS kit manually or want to enable reaction feature individually, open the `GlobalFeatureConfigurator` class in the `Domain.Shared` project and place the following code to the `Configure ` method. + +```csharp +GlobalFeatureManager.Instance.Modules.CmsKit(cmsKit => +{ + cmsKit.Reactions.Enable(); +}); +``` + +# Options + +## CmsKitReactionOptions + +You can use the reaction system to to add reactions feature to any kind of resource, like blog posts or comments, etc. The reaction system provides a mechanism to group reactions by entity types. For example, if you want to use the reaction system for products, you need to define an entity type named `Product`, and then add reactions under the defined entity type. + +`CmsKitReactionOptions` can be configured in the domain layer, in the `ConfigureServices` method of your [module](https://docs.abp.io/en/abp/latest/Module-Development-Basics). Example: + +```csharp +Configure(options => +{ + options.EntityTypes.Add( + new ReactionEntityTypeDefinition( + "Product", + reactions: new[] + { + new ReactionDefinition(StandardReactions.Smile), + new ReactionDefinition(StandardReactions.ThumbsUp), + new ReactionDefinition(StandardReactions.ThumbsDown), + new ReactionDefinition(StandardReactions.Confused), + new ReactionDefinition(StandardReactions.Eyes), + new ReactionDefinition(StandardReactions.Heart) + })); +}); +``` + +> If you're using the comment or blog features, the ABP framework defines predefined reactions for these features automatically. You can easily override or remove the predefined reactions in `Configure` method like shown above. + +`CmsKitReactionOptions` properties: + +- `EntityTypes`: List of defined entity types(`CmsKitReactionOptions`) in the reaction system. + +`ReactionEntityTypeDefinition` properties:asdas + +- `EntityType`: Name of the entity type. +- `Reactions`: List of defined reactions(`ReactionDefinition`) in the entity type. + +# Internals + +## Domain Layer + +#### Aggregates + +This module follows the [Entity Best Practices & Conventions](https://docs.abp.io/en/abp/latest/Best-Practices/Entities) guide. + +##### UserReaction + +A user reaction represents a given reaction from a user. + +- `UserReaction` (aggregate root): Represents a given reaction in the system. + +#### Repositories + +This module follows the [Repository Best Practices & Conventions](https://docs.abp.io/en/abp/latest/Best-Practices/Repositories) guide. + +Following custom repositories are defined for this feature: + +- `IUserReactionRepository` + +#### Domain services + +This module follows the [Domain Services Best Practices & Conventions](https://docs.abp.io/en/abp/latest/Best-Practices/Domain-Services) guide. + +##### Reaction Manager + +`ReactionManager` is used to perform some operations for the `UserReaction` aggregate root. + +### Application layer + +#### Application services + +- `ReactionPublicAppService` (implements `IReactionPublicAppService`): Implements the use cases of reaction system. + +### Database providers + +#### Common + +##### Table / collection prefix & schema + +All tables/collections use the `Cms` prefix by default. Set static properties on the `CmsKitDbProperties` class if you need to change the table prefix or set a schema name (if supported by your database provider). + +##### Connection string + +This module uses `CmsKit` for the connection string name. If you don't define a connection string with this name, it fallbacks to the `Default` connection string. + +See the [connection strings](https://docs.abp.io/en/abp/latest/Connection-Strings) documentation for details. + +#### Entity Framework Core + +##### Tables + +- CmsUserReactions + +#### MongoDB + +##### Collections + +- **CmsUserReactions** + +### MVC UI + +The reaction system provides a reaction widget to allow users to send reactions to resources on public websites. You can place the widget on a page like below. + +```csharp +@await Component.InvokeAsync(typeof(ReactionSelectionViewComponent), new +{ + entityType = "entityType", + entityId = "entityId" +}) +``` +You need to specify entity type and entity ID parameters. Entity type represents the group name you specified while defining the reactions in the domain module. Entity ID represents the unique identifier for the resource that users give reactions to, such as blog post ID or product ID. + +For more information about widgets see [widgets](https://docs.abp.io/en/abp/latest/UI/AspNetCore/Widgets) documentation. \ No newline at end of file diff --git a/docs/en/Modules/cms-kit/Tag-Management.md b/docs/en/Modules/cms-kit/Tag-Management.md new file mode 100644 index 0000000000..aa4b675dac --- /dev/null +++ b/docs/en/Modules/cms-kit/Tag-Management.md @@ -0,0 +1,135 @@ +# Tag Management + +CMS kit provides a **tag** system to tag any kind of resources, like blog posts. This section describes the details of the tag system. + +## Feature + +CMS kit uses the [global feature](https://docs.abp.io/en/abp/latest/Global-Features) system for all implemented features. Commercial startup templates come with all the CMS kit related features are enabled by default, if you create the solution with public website option. If you're installing the CMS kit manually or want to enable the tag management feature individually, open the `GlobalFeatureConfigurator` class in the `Domain.Shared` project and place the following code to the `Configure ` method. + +```csharp +GlobalFeatureManager.Instance.Modules.CmsKit(cmsKit => +{ + cmsKit.Tags.Enable(); +}); +``` + +# Options + +## CmsKitTagOptions + +You can use the tag system to tag any kind of resources, like blog posts, products, etc. The tag system provides a mechanism to group tags by entity types. For example, if you want to use the tag system for blog posts and products, you need to define two entity types named `BlogPosts` and `Product` and add tags under these entity types. + +`CmsKitTagOptions` can be configured in the domain layer, in the `ConfigureServices` method of your [module](https://docs.abp.io/en/abp/latest/Module-Development-Basics). Example: + +```csharp +Configure(options => +{ + options.EntityTypes.Add(new TagEntityTypeDefiniton("Product")); +}); +``` + +> If you're using the blog feature, the ABP framework defines an entity type for the blog feature automatically. You can easily override or remove the predefined entity types in `Configure` method like shown above. + +`CmsKitTagOptions` properties: + +- `EntityTypes`: List of defined entity types(`TagEntityTypeDefiniton`) in the tag system. + +`TagEntityTypeDefiniton` properties: + +- `EntityType`: Name of the entity type. +- `DisplayName`: Display name of the entity type. You can use a user friendly display name to show entity type definition on the admin website. +- `CreatePolicies`: List of policy names allowing users to create tags under the entity type. +- `UpdatePolicies`: List of policy names allowing users to update tags under the entity type. +- `DeletePolicies`: List of policy names allowing users to delete tags under the entity type. + +# Internals + +## Domain Layer + +#### Aggregates + +This module follows the [Entity Best Practices & Conventions](https://docs.abp.io/en/abp/latest/Best-Practices/Entities) guide. + +##### Tag + +A tag represents a tag under the entity type. + +- `Tag` (aggregate root): Represents a tag in the system. + +##### EntityTag + +An entity tag represents a connection between the tag and the tagged entity. + +- `EntityTag`(entity): Represents a connection between the tag and the tagged entity. + +#### Repositories + +This module follows the [Repository Best Practices & Conventions](https://docs.abp.io/en/abp/latest/Best-Practices/Repositories) guide. + +Following custom repositories are defined for this feature: + +- `ITagRepository` +- `IEntityTagRepository` + +#### Domain services + +This module follows the [Domain Services Best Practices & Conventions](https://docs.abp.io/en/abp/latest/Best-Practices/Domain-Services) guide. + +##### Tag Manager + +`TagManager` is used to perform some operations for the `Tag` aggregate root. + +##### Entity Tag Manager + +`EntityTagManager` is used to perform some operations for the `EntityTag` entity. + +### Application layer + +#### Application services + +- `TagAdminAppService` (implements `ITagAdminAppService`): Implements the use cases of tag management. +- `EntityTagAdminAppService` (implements `IEntityTagAdminAppService`): Implements the use cases of entity tag relationship. +- `TagAppService` (implements `ITagAppService`): Implements the use cases of entity tag relationship for public websites. + +### Database providers + +#### Common + +##### Table / collection prefix & schema + +All tables/collections use the `Cms` prefix by default. Set static properties on the `CmsKitDbProperties` class if you need to change the table prefix or set a schema name (if supported by your database provider). + +##### Connection string + +This module uses `CmsKit` for the connection string name. If you don't define a connection string with this name, it fallbacks to the `Default` connection string. + +See the [connection strings](https://docs.abp.io/en/abp/latest/Connection-Strings) documentation for details. + +#### Entity Framework Core + +##### Tables + +- CmsTags +- CmsEntityTags + - CmsTags + +#### MongoDB + +##### Collections + +- **CmsTags** +- **CmsEntityTags** + +### MVC UI + +The tag system provides a tag widget to display associated tags of the resource on public websites. You can simply place the widget on a page like below. + +```csharp +@await Component.InvokeAsync(typeof(TagViewComponent), new +{ + entityType = "entityType", + entityId = "entityId" +}) +``` + +For more information about widgets see [widgets](https://docs.abp.io/en/abp/latest/UI/AspNetCore/Widgets) documentation. \ No newline at end of file diff --git a/docs/en/MongoDB.md b/docs/en/MongoDB.md index a12d216b3d..d99c40da43 100644 --- a/docs/en/MongoDB.md +++ b/docs/en/MongoDB.md @@ -292,6 +292,24 @@ Configure(options => ### Advanced Topics +### Controlling the Multi-Tenancy + +If your solution is [multi-tenant](Multi-Tenancy.md), tenants may have **separate databases**, you have **multiple** `DbContext` classes in your solution and some of your `DbContext` classes should be usable **only from the host side**, it is suggested to add `[IgnoreMultiTenancy]` attribute on your `DbContext` class. In this case, ABP guarantees that the related `DbContext` always uses the host [connection string](Connection-Strings.md), even if you are in a tenant context. + +**Example:** + +````csharp +[IgnoreMultiTenancy] +public class MyDbContext : AbpMongoDbContext +{ + ... +} +```` + +Do not use the `[IgnoreMultiTenancy]` attribute if any one of your entities in your `DbContext` can be persisted in a tenant database. + +> When you use repositories, ABP already uses the host database for the entities don't implement the `IMultiTenant` interface. So, most of time you don't need to `[IgnoreMultiTenancy]` attribute if you are using the repositories to work with the database. + #### Set Default Repository Classes Default generic repositories are implemented by `MongoDbRepository` class by default. You can create your own implementation and use it for default repository implementation. @@ -373,7 +391,19 @@ One advantage of using interface for a MongoDbContext is then it becomes replace #### Replace Other DbContextes -Once you properly define and use an interface for a MongoDbContext , then any other implementation can replace it using the `ReplaceDbContext` option: +Once you properly define and use an interface for a MongoDbContext , then any other implementation can use the following ways to replace it: + +**ReplaceDbContextAttribute** + +```csharp +[ReplaceDbContext(typeof(IBookStoreMongoDbContext))] +public class OtherMongoDbContext : AbpMongoDbContext, IBookStoreMongoDbContext +{ + //... +} +``` + +**ReplaceDbContext option** ```csharp context.Services.AddMongoDbContext(options => diff --git a/docs/en/Road-Map.md b/docs/en/Road-Map.md index 02fba61320..f57e35c863 100644 --- a/docs/en/Road-Map.md +++ b/docs/en/Road-Map.md @@ -6,7 +6,7 @@ This document provides a road map, release schedule and planned features for the ### v4.4 -This version will focus on **documentation** and **improvements** of current features. In addition, the following features are planned; +This version will focus on **documentation** and **improvements** of current features. In addition, the following features are planned: * Publishing distributed events as transactional ([#6126](https://github.com/abpframework/abp/issues/6126)) * Revisit the microservice demo solution ([#8385](https://github.com/abpframework/abp/issues/8385)) @@ -15,26 +15,22 @@ This version will focus on **documentation** and **improvements** of current fea * Pre-configured test project for the [Blazor UI](UI/Blazor/Overall.md) ([#5516](https://github.com/abpframework/abp/issues/5516)) * Razor engine support for text templating ([#8373](https://github.com/abpframework/abp/issues/8373)) -**Planned release date**: End of Quarter 2, 2021. - -### v4.5 - -We planned to focus on v5.0 after 4.4 release. However, we may release v4.5 if we see it necessary. +**Planned release date**: End of Quarter 2, 2021. See the [4.4 milestone](https://github.com/abpframework/abp/milestone/52) to track the progress. ### v5.0 -This version will focus on .NET 6 and performance improvements. +We planned to focus on the ABP Framework v5.0 after the 4.4 release. This version will focus on the following works: -* Upgrading to .NET 6 -* .NET Trimming compatibility -* Using source generators and reducing reflection usage -* Performance improvements -* Improving the abp.io platform +* Upgrading to .NET 6.0 ([#9004](https://github.com/abpframework/abp/issues/9004)) +* Upgrading to Bootstrap 5.x ([#8922](https://github.com/abpframework/abp/issues/8922)) +* Alternative to IdentityServer4 ([#7221](https://github.com/abpframework/abp/issues/7221)) +* Dapr integration ([#2183](https://github.com/abpframework/abp/issues/2183)) +* Resource based authorization system ([#236](https://github.com/abpframework/abp/issues/236)) * API Versioning system: finalize & document ([#497](https://github.com/abpframework/abp/issues/497)) +* Performance optimizations; Enabling .NET Trimming, using source generators and reducing reflection, etc. +* Improving the abp.io platform and work more on contents and documents -**Planned release date**: End of Quarter 4, 2021. - -> Note: v5.0 features will be more clear in the next months. We will consider to add new features from the *Backlog Items*. +**Planned release date**: End of Quarter 4, 2021. See the [5.0 milestone](https://github.com/abpframework/abp/milestone/51) to track the progress. ## Backlog Items @@ -42,13 +38,10 @@ The *Next Versions* section above shows the main focus of the planned versions. Here, a list of major items in the backlog we are considering to work on in the next versions. -* [#2183](https://github.com/abpframework/abp/issues/2183) / Dapr integration * [#2882](https://github.com/abpframework/abp/issues/2882) / Providing a gRPC integration infrastructure (while it is [already possible](https://github.com/abpframework/abp-samples/tree/master/GrpcDemo) to create or consume gRPC endpoints for your application, we plan to create endpoints for the [standard application modules](https://docs.abp.io/en/abp/latest/Modules/Index)) -* [#633](https://github.com/abpframework/abp/issues/633) / Realtime notification system -* [#236](https://github.com/abpframework/abp/issues/236) / Resource based authorization system * [#1754](https://github.com/abpframework/abp/issues/1754) / Multi-lingual entities * [#57](https://github.com/abpframework/abp/issues/57) / Built-in CQRS infrastructure -* [#336](https://github.com/abpframework/abp/issues/336) / Health Check abstraction +* [#336](https://github.com/abpframework/abp/issues/336) / Health Check abstractions * [#2532](https://github.com/abpframework/abp/issues/2532), [#2564](https://github.com/abpframework/abp/issues/2465) / CosmosDB integration with EF Core and MongoDB API * [#4223](https://github.com/abpframework/abp/issues/4223) / WebHook system * [#162](https://github.com/abpframework/abp/issues/162) / Azure ElasticDB Integration for multitenancy diff --git a/docs/en/SimpleStateChecker.md b/docs/en/SimpleStateChecker.md new file mode 100644 index 0000000000..584fef1592 --- /dev/null +++ b/docs/en/SimpleStateChecker.md @@ -0,0 +1,125 @@ +# Simple State Checker + +The simple state checking system can be used to enable/disable an object based on some dynamic conditions. For example, you can disable a menu item on the user interface, if the current user has not granted for a given permission. The simple state checking system provides a generic way to define and check such conditions. + +## Definition state checker. + +Any class can inherit `IHasSimpleStateCheckers` to support state checks. + +````csharp +public class MyObject : IHasSimpleStateCheckers +{ + public int Id { get; set; } + + public List> SimpleStateCheckers { get; } + + public MyObject() + { + SimpleStateCheckers = new List>(); + } +} +```` + +The `MyObject` class contains a collection of state checkers, you can add your custom checkers to it. + +````csharp +public class MyObjectStateChecker : ISimpleStateChecker +{ + public Task IsEnabledAsync(SimpleStateCheckerContext context) + { + var currentUser = context.ServiceProvider.GetRequiredService(); + return Task.FromResult(currentUser.IsInRole("Admin")); + } +} +```` + +````csharp +var myobj = new MyObject() +{ + Id = 100 +}; + +myobj.SimpleStateCheckers.Add(new MyObjectStateChecker()); +```` + +## Definition Global State Checkers + +`AbpSimpleStateCheckerOptions` is the options class that used to set the global state checkers for specific object. + +Example: Add global state for `MyObject`: + +````csharp +services.Configure>(options => +{ + options.GlobalSimpleStateCheckers.Add(); + //options.GlobalSimpleStateCheckers.Add<>(); //Add more global state checkers +}); +```` + +> Write this inside the `ConfigureServices` method of your module. + +## Check the state + +You can inject `ISimpleStateCheckerManager` service to check state. + +````csharp +bool enabled = await stateCheckerManager.IsEnabledAsync(myobj); +```` + +### Batch check the states + +If there are many instance items that require state checking, there may be performance problems. + +In this case, you can implement `ISimpleBatchStateChecker`. It can check multiple items at once. +You need to make sure that the same `ISimpleBatchStateChecker` instance is added to the `SimpleStateCheckers` of multiple instances. + +> `SimpleBatchStateCheckerBase` inherits the `ISimpleBatchStateChecker` interface and implements the `IsEnabledAsync` method of a single object by default. + +````csharp +public class MyObjectBatchStateChecker : SimpleBatchStateCheckerBase +{ + public override Task> IsEnabledAsync(SimpleBatchStateCheckerContext context) + { + var result = new SimpleStateCheckerResult(context.States); + + foreach (var myObject in context.States) + { + if (myObject.Id > 100) + { + result[myObject] = true; + } + } + + return Task.FromResult(result); + } +} +```` + +````csharp +var myobj1 = new MyObject() +{ + Id = 100 +}; +var myobj2 = new MyObject() +{ + Id = 99 +}; + +var myObjectBatchStateChecker = new MyObjectBatchStateChecker(); + +myobj1.SimpleStateCheckers.Add(myObjectBatchStateChecker); +myobj2.SimpleStateCheckers.Add(myObjectBatchStateChecker); + +SimpleStateCheckerResult stateCheckerResult = await stateCheckerManager.IsEnabledAsync(new []{ myobj1, myobj2 }); +```` + +## Built-in State Checkers + +The `PermissionDefinition`, `ApplicationMenuItem` and `ToolbarItem` objects have implemented state checks and have built-in general state checkers, you can directly use their extension methods. + +````csharp +RequireAuthenticated(); +RequirePermissions(bool requiresAll, params string[] permissions); +RequireFeatures(bool requiresAll, params string[] features); +RequireGlobalFeatures(bool requiresAll, params Type[] globalFeatures); +```` diff --git a/docs/en/String-Encryption.md b/docs/en/String-Encryption.md index 81bb4f119a..867190365d 100644 --- a/docs/en/String-Encryption.md +++ b/docs/en/String-Encryption.md @@ -43,9 +43,9 @@ All encryption operations are included in `IStringEncryptionService`. You can in ```csharp public class MyService : DomainService { - public IStringEncryptionService StringEncryptionService { get; } + protected IStringEncryptionService StringEncryptionService { get; } - public MyAppService(IStringEncryptionService stringEncryptionService) + public MyService(IStringEncryptionService stringEncryptionService) { StringEncryptionService = stringEncryptionService; } @@ -69,11 +69,14 @@ All encryption operations are included in `IStringEncryptionService`. You can in `IStringEncryptionService` methods has **passPharase** parameter with default value and it uses default PassPhrase when you don't pass passPhrase parameter. ```csharp -StringEncryptionService.Encrypt(value); // Default Pass Phrase -StringEncryptionService.Encrypt(value, "MyCustomPassPhrase"); // Custom Pass Phrase +// Default Pass Phrase +var encryptedValue = StringEncryptionService.Encrypt(value); + +// Custom Pass Phrase +var encryptedValue = StringEncryptionService.Encrypt(value, "MyCustomPassPhrase"); // Encrypt & Decrypt have same parameters. -StringEncryptionService.Decrypt(value, "MyCustomPassPhrase"); +var decryptedValue = StringEncryptionService.Decrypt(value, "MyCustomPassPhrase"); ``` ### Using Custom Salt @@ -81,11 +84,14 @@ StringEncryptionService.Decrypt(value, "MyCustomPassPhrase"); `IStringEncryptionService` methods has **salt** parameter with default value and it uses default Salt when you don't pass the parameter. ```csharp -StringEncryptionService.Encrypt(value); // Default Salt -StringEncryptionService.Encrypt(value, salt: Encoding.UTF8.GetBytes("MyCustomSalt")); // Custom Salt +// Default Salt +var encryptedValue = StringEncryptionService.Encrypt(value); + +// Custom Salt +var encryptedValue = StringEncryptionService.Encrypt(value, salt: Encoding.UTF8.GetBytes("MyCustomSalt")); // Encrypt & Decrypt have same parameters. -StringEncryptionService.Decrypt(value, salt: Encoding.UTF8.GetBytes("MyCustomSalt")); +var decryptedValue = StringEncryptionService.Decrypt(value, salt: Encoding.UTF8.GetBytes("MyCustomSalt")); ``` *** @@ -116,4 +122,4 @@ Configure(opts => - **Keysize:** This constant is used to determine the keysize of the encryption algorithm. - Default value: `256` + Default value: `256` \ No newline at end of file diff --git a/docs/en/UI/Angular/Page-Component.md b/docs/en/UI/Angular/Page-Component.md index a9e9857142..912b516baf 100644 --- a/docs/en/UI/Angular/Page-Component.md +++ b/docs/en/UI/Angular/Page-Component.md @@ -1,4 +1,4 @@ -# Page Component +# Page Component ABP provides a component that wraps your content with some built-in components to reduce the amount of code you need to write. @@ -11,7 +11,7 @@ Let's look at the following example without `abp-page` component. ```html
-

{{ '::Dashboard' | abpLocalization }}

+

{%{{{ '::Dashboard' | abpLocalization }}}%}

``` -## Page Parts +## Page Parts PageComponent divides the template shown above into three parts, `title`, `breadcrumb`, `toolbar`. Each can be configured separately. There, also, is an enum exported from the package that describes each part. @@ -67,41 +67,35 @@ And change the template of `dashboard.component.ts` to the following: ``` -## Inputs +## Inputs * title: `string`: Will be be rendered within `h1.content-header-title`. If not provided, the parent `div` will not be rendered * breadcrumb: `boolean`: Determines whether to render `abp-breadcrumb`. Default is `true`. * toolbar: `any`: Will be passed into `abp-page-toolbar` component through `record` input. If your page does not contain `abp-page-toolbar`, you can simply omit this field. -## Overriding template +## Overriding template If you need to replace the template of any part, you can use the following sub-components. ```html - -
-

Custom Title

-
+ +

Custom Title

- -
- -
+ + - -
- -
+ +
``` You do not have to provide them all. You can just use which one you need to replace. These components have priority over the inputs declared above. If you use these components, you can omit the inputs. -## PagePartDirective +## PagePartDirective `PageModule` provides a structural directive that is used internally within `PageComponent` and can also be used externally. diff --git a/docs/en/UI/AspNetCore/Navigation-Menu.md b/docs/en/UI/AspNetCore/Navigation-Menu.md index 8480590f50..97e3d1a47d 100644 --- a/docs/en/UI/AspNetCore/Navigation-Menu.md +++ b/docs/en/UI/AspNetCore/Navigation-Menu.md @@ -104,7 +104,6 @@ There are more options of a menu item (the constructor of the `ApplicationMenuIt * `target` (`string`): Target of the menu item. Can be `null` (default), "\_*blank*", "\_*self*", "\_*parent*", "\_*top*" or a frame name for web applications. * `elementId` (`string`): Can be used to render the element with a specific HTML `id` attribute. * `cssClass` (`string`): Additional string classes for the menu item. -* `RequiredPermissionName` (`string`): The required permission name, this menu item will be removed if this permission is not granted. ### Authorization @@ -121,21 +120,21 @@ if (await context.IsGrantedAsync("MyPermissionName")) } ```` -For the authorization, you can use `RequiredPermissionName` as a shortcut. It is also more performant, ABP optimizes the permission check for all the items. +For the authorization, you can use `RequirePermissions` extension method as a shortcut. It is also more performant, ABP optimizes the permission check for all the items. ````csharp context.Menu.AddItem( new ApplicationMenuItem("MyProject.Crm", l["Menu:CRM"]) .AddItem(new ApplicationMenuItem( - name: "MyProject.Crm.Customers", - displayName: l["Menu:Customers"], - url: "/crm/customers", - requiredPermissionName: "MyProject.Crm.Customers") + name: "MyProject.Crm.Customers", + displayName: l["Menu:Customers"], + url: "/crm/customers") + .RequirePermissions("MyProject.Crm.Customers") ).AddItem(new ApplicationMenuItem( - name: "MyProject.Crm.Orders", - displayName: l["Menu:Orders"], - url: "/crm/orders", - requiredPermissionName: "MyProject.Crm.Orders") + name: "MyProject.Crm.Orders", + displayName: l["Menu:Orders"], + url: "/crm/orders") + .RequirePermissions("MyProject.Crm.Orders") ) ); ```` diff --git a/docs/en/UI/AspNetCore/Toolbars.md b/docs/en/UI/AspNetCore/Toolbars.md index 66ec7519b8..d82150b47e 100644 --- a/docs/en/UI/AspNetCore/Toolbars.md +++ b/docs/en/UI/AspNetCore/Toolbars.md @@ -61,10 +61,10 @@ if (await context.IsGrantedAsync("MyPermissionName")) } ```` -You can use `RequiredPermissionName` as a shortcut. It is also more performant, ABP optimizes the permission check for all the items. +You can use `RequirePermissions` extension method as a shortcut. It is also more performant, ABP optimizes the permission check for all the items. ````csharp -context.Toolbar.Items.Insert(0, new ToolbarItem(typeof(NotificationViewComponent), requiredPermissionName: "MyPermissionName")); +context.Toolbar.Items.Insert(0, new ToolbarItem(typeof(NotificationViewComponent)).RequirePermissions("MyPermissionName")); ```` This class adds the `NotificationViewComponent` as the first item in the `Main` toolbar. diff --git a/docs/en/docs-nav.json b/docs/en/docs-nav.json index 0a7722de78..fe2de7ce3c 100644 --- a/docs/en/docs-nav.json +++ b/docs/en/docs-nav.json @@ -39,31 +39,6 @@ } ] }, - { - "text": "Startup Templates", - "items": [ - { - "text": "Overall", - "path": "Startup-Templates/Index.md" - }, - { - "text": "Application", - "path": "Startup-Templates/Application.md" - }, - { - "text": "Module", - "path": "Startup-Templates/Module.md" - }, - { - "text": "Console", - "path": "Startup-Templates/Console.md" - }, - { - "text": "WPF", - "path": "Startup-Templates/WPF.md" - } - ] - }, { "text": "Tutorials", "items": [ @@ -122,6 +97,45 @@ } ] }, + { + "text": "CLI", + "path": "CLI.md", + "items": [ + { + "text": "Build Command", + "path": "CLI-BuildCommand.md" + }, + { + "text": "Create Solution Sample Commands", + "path": "CLI-New-Command-Samples.md" + } + ] + }, + { + "text": "Startup Templates", + "items": [ + { + "text": "Overall", + "path": "Startup-Templates/Index.md" + }, + { + "text": "Application", + "path": "Startup-Templates/Application.md" + }, + { + "text": "Module", + "path": "Startup-Templates/Module.md" + }, + { + "text": "Console", + "path": "Startup-Templates/Console.md" + }, + { + "text": "WPF", + "path": "Startup-Templates/WPF.md" + } + ] + }, { "text": "Fundamentals", "items": [ @@ -379,6 +393,10 @@ { "text": "Cancellation Token Provider", "path": "Cancellation-Token-Provider.md" + }, + { + "text": "Simple State Checker", + "path": "SimpleStateChecker.md" } ] }, @@ -1292,25 +1310,6 @@ } ] }, - { - "text": "Reference", - "items": [ - { - "text": "CLI", - "path": "CLI.md", - "items": [ - { - "text": "Build Command", - "path": "CLI-BuildCommand.md" - }, - { - "text": "Create Solution Sample Commands", - "path": "CLI-New-Command-Samples.md" - } - ] - } - ] - }, { "text": "Contribution Guide", "path": "Contribution/Index.md" diff --git a/docs/en/images/cmskit-module-blog-post-edit.png b/docs/en/images/cmskit-module-blog-post-edit.png new file mode 100644 index 0000000000..528bc6b499 Binary files /dev/null and b/docs/en/images/cmskit-module-blog-post-edit.png differ diff --git a/docs/en/images/cmskit-module-blog-posts-page.png b/docs/en/images/cmskit-module-blog-posts-page.png new file mode 100644 index 0000000000..64d5d0e934 Binary files /dev/null and b/docs/en/images/cmskit-module-blog-posts-page.png differ diff --git a/docs/en/images/cmskit-module-blogs-edit.png b/docs/en/images/cmskit-module-blogs-edit.png new file mode 100644 index 0000000000..b2da4e5b5a Binary files /dev/null and b/docs/en/images/cmskit-module-blogs-edit.png differ diff --git a/docs/en/images/cmskit-module-blogs-feature-action.png b/docs/en/images/cmskit-module-blogs-feature-action.png new file mode 100644 index 0000000000..c0f0b1d3f4 Binary files /dev/null and b/docs/en/images/cmskit-module-blogs-feature-action.png differ diff --git a/docs/en/images/cmskit-module-blogs-page.png b/docs/en/images/cmskit-module-blogs-page.png new file mode 100644 index 0000000000..6c150429b7 Binary files /dev/null and b/docs/en/images/cmskit-module-blogs-page.png differ diff --git a/docs/en/images/cmskit-module-comment-page.png b/docs/en/images/cmskit-module-comment-page.png new file mode 100644 index 0000000000..6647a6dd09 Binary files /dev/null and b/docs/en/images/cmskit-module-comment-page.png differ diff --git a/docs/en/images/cmskit-module-comments-detail.png b/docs/en/images/cmskit-module-comments-detail.png new file mode 100644 index 0000000000..686a70e1f8 Binary files /dev/null and b/docs/en/images/cmskit-module-comments-detail.png differ diff --git a/docs/en/images/cmskit-module-features-dialog.png b/docs/en/images/cmskit-module-features-dialog.png new file mode 100644 index 0000000000..23aa2aa17a Binary files /dev/null and b/docs/en/images/cmskit-module-features-dialog.png differ diff --git a/docs/en/images/cmskit-module-pages-edit.png b/docs/en/images/cmskit-module-pages-edit.png new file mode 100644 index 0000000000..cca074fdac Binary files /dev/null and b/docs/en/images/cmskit-module-pages-edit.png differ diff --git a/docs/en/images/cmskit-module-pages-page.png b/docs/en/images/cmskit-module-pages-page.png new file mode 100644 index 0000000000..b64915493c Binary files /dev/null and b/docs/en/images/cmskit-module-pages-page.png differ diff --git a/docs/en/images/cmskit-module-ratings.png b/docs/en/images/cmskit-module-ratings.png new file mode 100644 index 0000000000..f97c934f15 Binary files /dev/null and b/docs/en/images/cmskit-module-ratings.png differ diff --git a/docs/en/images/cmskit-module-reactions.png b/docs/en/images/cmskit-module-reactions.png new file mode 100644 index 0000000000..b915b85f91 Binary files /dev/null and b/docs/en/images/cmskit-module-reactions.png differ diff --git a/docs/en/images/cmskit-module-tag-edit.png b/docs/en/images/cmskit-module-tag-edit.png new file mode 100644 index 0000000000..eb1ebb3a52 Binary files /dev/null and b/docs/en/images/cmskit-module-tag-edit.png differ diff --git a/docs/en/images/cmskit-module-tags-page.png b/docs/en/images/cmskit-module-tags-page.png new file mode 100644 index 0000000000..f41b6ecbd0 Binary files /dev/null and b/docs/en/images/cmskit-module-tags-page.png differ diff --git a/docs/zh-Hans/Blob-Storing-Minio.md b/docs/zh-Hans/Blob-Storing-Minio.md index fb98281f02..bc0268b5cf 100644 --- a/docs/zh-Hans/Blob-Storing-Minio.md +++ b/docs/zh-Hans/Blob-Storing-Minio.md @@ -42,7 +42,7 @@ Configure(options => * **EndPoint** (string): 你的Minio对象存储服务的URL, 查看文档:https://docs.min.io/docs/dotnet-client-quickstart-guide.html * **AccessKey** (string): Access key是唯一标识你的账户的用户ID, -* **SecretKey** (string): Access key是唯一标识你的账户的用户ID +* **SecretKey** (string): Secret Key是你的账户的密码 * **BucketName** (string):你可以指定bucket名称,如果没有指定,将使用 `BlobContainerName` 属性定义的BLOB容器的名称(查阅[BLOB storing document](Blob-Storing.md)),MinIO完全兼容S3标准,所以有一些 **bucket命名规则**,必须符合[规则](https://docs.aws.amazon.com/AmazonS3/latest/dev/BucketRestrictions.html): * Bucket名称必须介于 3 到 63 个字符之间. * Bucket名称只能由小写字母、数字、句点 (.) 和连字符 (-) 组成. diff --git a/docs/zh-Hans/Entity-Framework-Core.md b/docs/zh-Hans/Entity-Framework-Core.md index b5252b86c0..4139407f04 100644 --- a/docs/zh-Hans/Entity-Framework-Core.md +++ b/docs/zh-Hans/Entity-Framework-Core.md @@ -433,7 +433,19 @@ public class BookRepository : EfCoreRepository, ### 替换其他仓储 -正确定义并使用DbContext接口后,任何其他实现都可以使用以下ReplaceDbContext options 替换它: +正确定义并使用DbContext接口后,任何其他实现都可以使用以下方法替换它: + +**ReplaceDbContextAttribute** + +```csharp +[ReplaceDbContext(typeof(IBookStoreDbContext))] +public class OtherDbContext : AbpDbContext, IBookStoreDbContext +{ + //... +} +``` + +**ReplaceDbContext option** ````csharp context.Services.AddAbpDbContext(options => diff --git a/docs/zh-Hans/MongoDB.md b/docs/zh-Hans/MongoDB.md index af63642a41..87c99d3207 100644 --- a/docs/zh-Hans/MongoDB.md +++ b/docs/zh-Hans/MongoDB.md @@ -329,7 +329,19 @@ public class BookRepository ##### 替换其他的DbContexts -一旦你正确定义并为MongoDbContext使用了接口,其他的实现就可以使用`ReplaceDbContext`来替换: +一旦你正确定义并为MongoDbContext使用了接口,任何其他实现都可以使用以下方法替换它: + +**ReplaceDbContextAttribute** + +```csharp +[ReplaceDbContext(typeof(IBookStoreMongoDbContext))] +public class OtherMongoDbContext : AbpMongoDbContext, IBookStoreMongoDbContext +{ + //... +} +``` + +**ReplaceDbContext option** ```csharp context.Services.AddMongoDbContext(options => diff --git a/docs/zh-Hans/Tutorials/Part-1.md b/docs/zh-Hans/Tutorials/Part-1.md index e459c8b960..8c1c90e5d6 100644 --- a/docs/zh-Hans/Tutorials/Part-1.md +++ b/docs/zh-Hans/Tutorials/Part-1.md @@ -84,7 +84,7 @@ namespace Acme.BookStore.Books } ```` -* ABP为实体提供了两个基本的基类: `AggregateRoot`和`Entity`. **Aggregate Root**是[**领域驱动设计**](./Domain-Driven-Design.md) 概念之一. 可以视为直接查询和处理的根实体(请参阅[实体文档](./Entities.md)). +* ABP为实体提供了两个基本的基类: `AggregateRoot`和`Entity`. **Aggregate Root**是[**领域驱动设计**](./Domain-Driven-Design.md) 概念之一. 可以视为直接查询和处理的根实体(请参阅[实体文档](../Entities.md)). * `Book`实体继承了`AuditedAggregateRoot`,`AuditedAggregateRoot`类在`AggregateRoot`类的基础上添加了一些审计属性(`CreationTime`, `CreatorId`, `LastModificationTime` 等). ABP框架自动为你管理这些属性. * `Guid`是`Book`实体的主键类型. diff --git a/docs/zh-Hans/Tutorials/Part-3.md b/docs/zh-Hans/Tutorials/Part-3.md index fec101c2a2..90dd1326c3 100644 --- a/docs/zh-Hans/Tutorials/Part-3.md +++ b/docs/zh-Hans/Tutorials/Part-3.md @@ -398,7 +398,7 @@ namespace Acme.BookStore.Web 我们将为表格每行添加下拉按钮 ("Actions"): -打开 `Pages/Books/Index.cshtml` 页面,并按下方所示修改表格部分的代码: +打开 `Pages/Books/Index.js` 页面,并按下方所示修改表格部分的代码: ````js $(function () { diff --git a/framework/Volo.Abp.sln b/framework/Volo.Abp.sln index 160918667d..b71288ab93 100644 --- a/framework/Volo.Abp.sln +++ b/framework/Volo.Abp.sln @@ -395,6 +395,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Abp.TextTemplating.Raz EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Abp.TextTemplating.Scriban.Tests", "test\Volo.Abp.TextTemplating.Scriban.Tests\Volo.Abp.TextTemplating.Scriban.Tests.csproj", "{75D8DADB-3FA9-4C1D-B23A-DBFD08133B7C}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Abp.MongoDB.Tests.SecondContext", "test\Volo.Abp.MongoDB.Tests.SecondContext\Volo.Abp.MongoDB.Tests.SecondContext.csproj", "{90B1866A-EF99-40B9-970E-B898E5AA523F}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -1177,6 +1179,10 @@ Global {75D8DADB-3FA9-4C1D-B23A-DBFD08133B7C}.Debug|Any CPU.Build.0 = Debug|Any CPU {75D8DADB-3FA9-4C1D-B23A-DBFD08133B7C}.Release|Any CPU.ActiveCfg = Release|Any CPU {75D8DADB-3FA9-4C1D-B23A-DBFD08133B7C}.Release|Any CPU.Build.0 = Release|Any CPU + {90B1866A-EF99-40B9-970E-B898E5AA523F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {90B1866A-EF99-40B9-970E-B898E5AA523F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {90B1866A-EF99-40B9-970E-B898E5AA523F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {90B1866A-EF99-40B9-970E-B898E5AA523F}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -1376,6 +1382,7 @@ Global {42EA6F06-2D78-4D18-8AC4-8F2AB7E6DA19} = {5DF0E140-0513-4D0D-BE2E-3D4D85CD70E6} {C996F458-98FB-483D-9306-4701290E2FC1} = {447C8A77-E5F0-4538-8687-7383196D04EA} {75D8DADB-3FA9-4C1D-B23A-DBFD08133B7C} = {447C8A77-E5F0-4538-8687-7383196D04EA} + {90B1866A-EF99-40B9-970E-B898E5AA523F} = {447C8A77-E5F0-4538-8687-7383196D04EA} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {BB97ECF4-9A84-433F-A80B-2A3285BDD1D5} diff --git a/framework/src/Volo.Abp.AspNetCore.Authentication.OpenIdConnect/Microsoft/Extensions/DependencyInjection/AbpOpenIdConnectExtensions.cs b/framework/src/Volo.Abp.AspNetCore.Authentication.OpenIdConnect/Microsoft/Extensions/DependencyInjection/AbpOpenIdConnectExtensions.cs index e98280d19d..160e66f49f 100644 --- a/framework/src/Volo.Abp.AspNetCore.Authentication.OpenIdConnect/Microsoft/Extensions/DependencyInjection/AbpOpenIdConnectExtensions.cs +++ b/framework/src/Volo.Abp.AspNetCore.Authentication.OpenIdConnect/Microsoft/Extensions/DependencyInjection/AbpOpenIdConnectExtensions.cs @@ -4,6 +4,7 @@ using Microsoft.AspNetCore.Authentication; using Microsoft.AspNetCore.Authentication.OAuth.Claims; using Microsoft.AspNetCore.Authentication.OpenIdConnect; using Microsoft.Extensions.Options; +using Microsoft.IdentityModel.Protocols.OpenIdConnect; using Volo.Abp.AspNetCore.MultiTenancy; namespace Microsoft.Extensions.DependencyInjection @@ -35,6 +36,17 @@ namespace Microsoft.Extensions.DependencyInjection SetAbpTenantId(receivedContext); return authorizationCodeReceived.Invoke(receivedContext); }; + + options.Events.OnRemoteFailure = remoteFailureContext => + { + if (remoteFailureContext.Failure is OpenIdConnectProtocolException && + remoteFailureContext.Failure.Message.Contains("access_denied")) + { + remoteFailureContext.HandleResponse(); + remoteFailureContext.Response.Redirect($"{remoteFailureContext.Request.PathBase}/"); + } + return Task.CompletedTask; + }; }); } diff --git a/framework/src/Volo.Abp.AspNetCore.Components.Web.BasicTheme/Themes/Basic/AppWithoutAuth.razor b/framework/src/Volo.Abp.AspNetCore.Components.Web.BasicTheme/Themes/Basic/AppWithoutAuth.razor new file mode 100644 index 0000000000..e9bf522595 --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Components.Web.BasicTheme/Themes/Basic/AppWithoutAuth.razor @@ -0,0 +1,14 @@ +@using Microsoft.Extensions.Options +@using Volo.Abp.AspNetCore.Components.Web.Theming.Routing +@inject IOptions RouterOptions + + + + + + +

Sorry, there's nothing at this address.

+
+
+
\ No newline at end of file diff --git a/framework/src/Volo.Abp.AspNetCore.Components.Web/Volo/Abp/AspNetCore/Components/Web/Security/AbpComponentsClaimsCache.cs b/framework/src/Volo.Abp.AspNetCore.Components.Web/Volo/Abp/AspNetCore/Components/Web/Security/AbpComponentsClaimsCache.cs index 281b2f7ded..787bf5cb6e 100644 --- a/framework/src/Volo.Abp.AspNetCore.Components.Web/Volo/Abp/AspNetCore/Components/Web/Security/AbpComponentsClaimsCache.cs +++ b/framework/src/Volo.Abp.AspNetCore.Components.Web/Volo/Abp/AspNetCore/Components/Web/Security/AbpComponentsClaimsCache.cs @@ -1,5 +1,6 @@ using System.Security.Claims; using System.Threading.Tasks; +using JetBrains.Annotations; using Microsoft.AspNetCore.Components.Authorization; using Microsoft.Extensions.DependencyInjection; using Volo.Abp.DependencyInjection; @@ -14,21 +15,29 @@ namespace Volo.Abp.AspNetCore.Components.Web.Security { public ClaimsPrincipal Principal { get; private set; } + [CanBeNull] private readonly AuthenticationStateProvider _authenticationStateProvider; - public AbpComponentsClaimsCache(IClientScopeServiceProviderAccessor clientScopeServiceProviderAccessor) + public AbpComponentsClaimsCache( + IClientScopeServiceProviderAccessor serviceProviderAccessor) { - _authenticationStateProvider = clientScopeServiceProviderAccessor.ServiceProvider.GetRequiredService(); - _authenticationStateProvider.AuthenticationStateChanged += async (task) => + _authenticationStateProvider = serviceProviderAccessor.ServiceProvider.GetService(); + if (_authenticationStateProvider != null) { - Principal = (await task).User; - }; + _authenticationStateProvider.AuthenticationStateChanged += async (task) => + { + Principal = (await task).User; + }; + } } public virtual async Task InitializeAsync() { - var authenticationState = await _authenticationStateProvider.GetAuthenticationStateAsync(); - Principal = authenticationState.User; + if (_authenticationStateProvider != null) + { + var authenticationState = await _authenticationStateProvider.GetAuthenticationStateAsync(); + Principal = authenticationState.User; + } } } } diff --git a/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme/BasicThemeToolbarContributor.cs b/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme/BasicThemeToolbarContributor.cs index ab2a73a8dd..b853670d39 100644 --- a/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme/BasicThemeToolbarContributor.cs +++ b/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme/BasicThemeToolbarContributor.cs @@ -1,7 +1,10 @@ using System.Threading.Tasks; +using Microsoft.AspNetCore.Components.Authorization; +using Microsoft.Extensions.DependencyInjection; using Volo.Abp.AspNetCore.Components.Web.BasicTheme.Themes.Basic; using Volo.Abp.AspNetCore.Components.Web.Theming.Toolbars; using Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme.Themes.Basic; +using Volo.Abp.DependencyInjection; namespace Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme { @@ -12,7 +15,15 @@ namespace Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme if (context.Toolbar.Name == StandardToolbars.Main) { context.Toolbar.Items.Add(new ToolbarItem(typeof(LanguageSwitch))); - context.Toolbar.Items.Add(new ToolbarItem(typeof(LoginDisplay))); + + //TODO: Can we find a different way to understand if authentication was configured or not? + var authenticationStateProvider = context.ServiceProvider + .GetService(); + + if (authenticationStateProvider != null) + { + context.Toolbar.Items.Add(new ToolbarItem(typeof(LoginDisplay))); + } } return Task.CompletedTask; diff --git a/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme/Themes/Basic/LoginDisplay.razor b/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme/Themes/Basic/LoginDisplay.razor index eebfb501a5..1b084a60ce 100644 --- a/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme/Themes/Basic/LoginDisplay.razor +++ b/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme/Themes/Basic/LoginDisplay.razor @@ -1,13 +1,12 @@ -@using Microsoft.AspNetCore.Components.WebAssembly.Authentication -@using Microsoft.Extensions.Localization +@using Microsoft.Extensions.Localization @using Volo.Abp.Users @using Volo.Abp.MultiTenancy @using global::Localization.Resources.AbpUi +@inherits AbpComponentBase @inject ICurrentUser CurrentUser @inject ICurrentTenant CurrentTenant @inject IJSRuntime JsRuntime @inject NavigationManager Navigation -@inject SignOutSessionStateManager SignOutManager @inject IStringLocalizer UiLocalizer @@ -38,24 +37,4 @@ @UiLocalizer["Login"] - -@code{ - - private async Task NavigateToAsync(string uri, string target = null) - { - if (target == "_blank") - { - await JsRuntime.InvokeVoidAsync("open", uri, target); - } - else - { - Navigation.NavigateTo(uri); - } - } - - private async Task BeginSignOut() - { - await SignOutManager.SetSignOutState(); - await NavigateToAsync("authentication/logout"); - } -} + \ No newline at end of file diff --git a/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme/Themes/Basic/LoginDisplay.razor.cs b/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme/Themes/Basic/LoginDisplay.razor.cs index addef3dc80..0ec9caa23c 100644 --- a/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme/Themes/Basic/LoginDisplay.razor.cs +++ b/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme/Themes/Basic/LoginDisplay.razor.cs @@ -1,8 +1,11 @@ using System; using System.Threading.Tasks; +using JetBrains.Annotations; using Microsoft.AspNetCore.Components; using Microsoft.AspNetCore.Components.Authorization; using Microsoft.AspNetCore.Components.Routing; +using Microsoft.AspNetCore.Components.WebAssembly.Authentication; +using Microsoft.JSInterop; using Volo.Abp.UI.Navigation; namespace Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme.Themes.Basic @@ -11,23 +14,32 @@ namespace Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme.Themes.Basic { [Inject] protected IMenuManager MenuManager { get; set; } - - [Inject] - protected AuthenticationStateProvider AuthenticationStateProvider { get; set; } - protected ApplicationMenu Menu { get; set; } + [CanBeNull] + protected AuthenticationStateProvider AuthenticationStateProvider; + + [CanBeNull] + protected SignOutSessionStateManager SignOutManager; + protected ApplicationMenu Menu { get; set; } + protected override async Task OnInitializedAsync() { Menu = await MenuManager.GetAsync(StandardMenus.User); Navigation.LocationChanged += OnLocationChanged; - AuthenticationStateProvider.AuthenticationStateChanged += async (task) => + LazyGetService(ref AuthenticationStateProvider); + LazyGetService(ref SignOutManager); + + if (AuthenticationStateProvider != null) { - Menu = await MenuManager.GetAsync(StandardMenus.User); - await InvokeAsync(StateHasChanged); - }; + AuthenticationStateProvider.AuthenticationStateChanged += async (task) => + { + Menu = await MenuManager.GetAsync(StandardMenus.User); + await InvokeAsync(StateHasChanged); + }; + } } protected virtual void OnLocationChanged(object sender, LocationChangedEventArgs e) @@ -39,5 +51,26 @@ namespace Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme.Themes.Basic { Navigation.LocationChanged -= OnLocationChanged; } + + private async Task NavigateToAsync(string uri, string target = null) + { + if (target == "_blank") + { + await JsRuntime.InvokeVoidAsync("open", uri, target); + } + else + { + Navigation.NavigateTo(uri); + } + } + + private async Task BeginSignOut() + { + if (SignOutManager != null) + { + await SignOutManager.SetSignOutState(); + await NavigateToAsync("authentication/logout"); + } + } } } diff --git a/framework/src/Volo.Abp.AspNetCore.Components/Volo/Abp/AspNetCore/Components/AbpComponentBase.cs b/framework/src/Volo.Abp.AspNetCore.Components/Volo/Abp/AspNetCore/Components/AbpComponentBase.cs index bc4db53002..163b2217fa 100644 --- a/framework/src/Volo.Abp.AspNetCore.Components/Volo/Abp/AspNetCore/Components/AbpComponentBase.cs +++ b/framework/src/Volo.Abp.AspNetCore.Components/Volo/Abp/AspNetCore/Components/AbpComponentBase.cs @@ -108,6 +108,18 @@ namespace Volo.Abp.AspNetCore.Components return reference; } + + protected TService LazyGetService(ref TService reference) => LazyGetService(typeof(TService), ref reference); + + protected TRef LazyGetService(Type serviceType, ref TRef reference) + { + if (reference == null) + { + reference = (TRef)ScopedServices.GetService(serviceType); + } + + return reference; + } protected TService LazyGetNonScopedRequiredService(ref TService reference) => LazyGetNonScopedRequiredService(typeof(TService), ref reference); @@ -120,6 +132,18 @@ namespace Volo.Abp.AspNetCore.Components return reference; } + + protected TService LazyGetNonScopedService(ref TService reference) => LazyGetNonScopedService(typeof(TService), ref reference); + + protected TRef LazyGetNonScopedService(Type serviceType, ref TRef reference) + { + if (reference == null) + { + reference = (TRef)NonScopedServices.GetService(serviceType); + } + + return reference; + } [Inject] protected IServiceProvider NonScopedServices { get; set; } diff --git a/framework/src/Volo.Abp.AspNetCore.MultiTenancy/Volo/Abp/AspNetCore/MultiTenancy/AbpAspNetCoreMultiTenancyOptions.cs b/framework/src/Volo.Abp.AspNetCore.MultiTenancy/Volo/Abp/AspNetCore/MultiTenancy/AbpAspNetCoreMultiTenancyOptions.cs index 63b83885f9..b2ecf708c5 100644 --- a/framework/src/Volo.Abp.AspNetCore.MultiTenancy/Volo/Abp/AspNetCore/MultiTenancy/AbpAspNetCoreMultiTenancyOptions.cs +++ b/framework/src/Volo.Abp.AspNetCore.MultiTenancy/Volo/Abp/AspNetCore/MultiTenancy/AbpAspNetCoreMultiTenancyOptions.cs @@ -1,4 +1,9 @@ -using Volo.Abp.MultiTenancy; +using System; +using System.Globalization; +using System.Net; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Http; +using Volo.Abp.MultiTenancy; namespace Volo.Abp.AspNetCore.MultiTenancy { @@ -9,9 +14,26 @@ namespace Volo.Abp.AspNetCore.MultiTenancy /// public string TenantKey { get; set; } + public Func MultiTenancyMiddlewareErrorPageBuilder { get; set; } + public AbpAspNetCoreMultiTenancyOptions() { TenantKey = TenantResolverConsts.DefaultTenantKey; + MultiTenancyMiddlewareErrorPageBuilder = async (context, exception)=> + { + context.Response.StatusCode = (int) HttpStatusCode.InternalServerError;; + context.Response.ContentType = "text/html"; + + var message = exception.Message; + var details = exception is BusinessException businessException ? businessException.Details : string.Empty; + + await context.Response.WriteAsync($"\r\n"); + await context.Response.WriteAsync($"

{message}

{details}
\r\n"); + await context.Response.WriteAsync("\r\n"); + + // Note the 500 spaces are to work around an IE 'feature' + await context.Response.WriteAsync(new string(' ', 500)); + }; } } -} \ No newline at end of file +} diff --git a/framework/src/Volo.Abp.AspNetCore.MultiTenancy/Volo/Abp/AspNetCore/MultiTenancy/MultiTenancyMiddleware.cs b/framework/src/Volo.Abp.AspNetCore.MultiTenancy/Volo/Abp/AspNetCore/MultiTenancy/MultiTenancyMiddleware.cs index eaf5c753fd..361826672b 100644 --- a/framework/src/Volo.Abp.AspNetCore.MultiTenancy/Volo/Abp/AspNetCore/MultiTenancy/MultiTenancyMiddleware.cs +++ b/framework/src/Volo.Abp.AspNetCore.MultiTenancy/Volo/Abp/AspNetCore/MultiTenancy/MultiTenancyMiddleware.cs @@ -1,10 +1,14 @@ using System; using System.Globalization; +using System.IO; +using System.Net; using System.Threading.Tasks; +using Microsoft.AspNetCore.Diagnostics; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Localization; using Microsoft.AspNetCore.RequestLocalization; using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Options; using Volo.Abp.DependencyInjection; using Volo.Abp.Localization; using Volo.Abp.MultiTenancy; @@ -16,18 +20,31 @@ namespace Volo.Abp.AspNetCore.MultiTenancy { private readonly ITenantConfigurationProvider _tenantConfigurationProvider; private readonly ICurrentTenant _currentTenant; + private readonly AbpAspNetCoreMultiTenancyOptions _options; public MultiTenancyMiddleware( ITenantConfigurationProvider tenantConfigurationProvider, - ICurrentTenant currentTenant) + ICurrentTenant currentTenant, + IOptions options) { _tenantConfigurationProvider = tenantConfigurationProvider; _currentTenant = currentTenant; + _options = options.Value; } public async Task InvokeAsync(HttpContext context, RequestDelegate next) { - var tenant = await _tenantConfigurationProvider.GetAsync(saveResolveResult: true); + TenantConfiguration tenant; + try + { + tenant = await _tenantConfigurationProvider.GetAsync(saveResolveResult: true); + } + catch (Exception e) + { + await _options.MultiTenancyMiddlewareErrorPageBuilder(context, e); + return; + } + if (tenant?.Id != _currentTenant.Id) { using (_currentTenant.Change(tenant?.Id, tenant?.Name)) diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.Contracts/Volo/Abp/AspNetCore/Mvc/MultiTenancy/FindTenantResultDto.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.Contracts/Volo/Abp/AspNetCore/Mvc/MultiTenancy/FindTenantResultDto.cs index d85622f0cf..6f834b18ea 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.Contracts/Volo/Abp/AspNetCore/Mvc/MultiTenancy/FindTenantResultDto.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.Contracts/Volo/Abp/AspNetCore/Mvc/MultiTenancy/FindTenantResultDto.cs @@ -10,5 +10,7 @@ namespace Volo.Abp.AspNetCore.Mvc.MultiTenancy public Guid? TenantId { get; set; } public string Name { get; set; } + + public bool IsActive { get; set; } } -} \ No newline at end of file +} diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpSelectTagHelper.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpSelectTagHelper.cs index 8c4c9465d0..20ade14b49 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpSelectTagHelper.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpSelectTagHelper.cs @@ -12,6 +12,8 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form public string Label { get; set; } + public bool SuppressLabel { get; set; } + public IEnumerable AspItems { get; set; } public AbpFormControlSize Size { get; set; } = AbpFormControlSize.Default; diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpSelectTagHelperService.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpSelectTagHelperService.cs index 24290487d5..f651c24874 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpSelectTagHelperService.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpSelectTagHelperService.cs @@ -168,6 +168,11 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form protected virtual async Task GetLabelAsHtmlAsync(TagHelperContext context, TagHelperOutput output, TagHelperOutput selectTag) { + if (TagHelper.SuppressLabel) + { + return string.Empty; + } + if (!string.IsNullOrEmpty(TagHelper.Label)) { var label = new TagBuilder("label"); diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy/Pages/Abp/MultiTenancy/AbpTenantAppService.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy/Pages/Abp/MultiTenancy/AbpTenantAppService.cs index d0bea87196..60bdb523ba 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy/Pages/Abp/MultiTenancy/AbpTenantAppService.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy/Pages/Abp/MultiTenancy/AbpTenantAppService.cs @@ -28,10 +28,11 @@ namespace Pages.Abp.MultiTenancy { Success = true, TenantId = tenant.Id, - Name = tenant.Name + Name = tenant.Name, + IsActive = tenant.IsActive }; } - + public async Task FindTenantByIdAsync(Guid id) { var tenant = await TenantStore.FindAsync(id); @@ -45,8 +46,9 @@ namespace Pages.Abp.MultiTenancy { Success = true, TenantId = tenant.Id, - Name = tenant.Name + Name = tenant.Name, + IsActive = tenant.IsActive }; } } -} \ No newline at end of file +} diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy/Pages/Abp/MultiTenancy/TenantSwitchModal.cshtml.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy/Pages/Abp/MultiTenancy/TenantSwitchModal.cshtml.cs index bfdbb98db8..f47edab789 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy/Pages/Abp/MultiTenancy/TenantSwitchModal.cshtml.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy/Pages/Abp/MultiTenancy/TenantSwitchModal.cshtml.cs @@ -20,7 +20,7 @@ namespace Pages.Abp.MultiTenancy protected AbpAspNetCoreMultiTenancyOptions Options { get; } public TenantSwitchModalModel( - ITenantStore tenantStore, + ITenantStore tenantStore, IOptions options) { TenantStore = tenantStore; @@ -49,6 +49,11 @@ namespace Pages.Abp.MultiTenancy { var tenant = await TenantStore.FindAsync(Input.Name); if (tenant == null) + { + throw new UserFriendlyException(L["GivenTenantIsNotExist", Input.Name]); + } + + if (!tenant.IsActive) { throw new UserFriendlyException(L["GivenTenantIsNotAvailable", Input.Name]); } @@ -71,4 +76,4 @@ namespace Pages.Abp.MultiTenancy public string Name { get; set; } } } -} \ No newline at end of file +} diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy/Volo/Abp/AspNetCore/Mvc/UI/MultiTenancy/Localization/ar.json b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy/Volo/Abp/AspNetCore/Mvc/UI/MultiTenancy/Localization/ar.json index 7e5f26edc6..fafc04a6ee 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy/Volo/Abp/AspNetCore/Mvc/UI/MultiTenancy/Localization/ar.json +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy/Volo/Abp/AspNetCore/Mvc/UI/MultiTenancy/Localization/ar.json @@ -1,6 +1,7 @@ { "culture": "ar", "texts": { + "GivenTenantIsNotExist": "المستأجر المحدد غير موجود: {0}", "GivenTenantIsNotAvailable": "الجهة المحددة غير متاحة: {0}", "Tenant": "الجهة", "Switch": "تغيير", @@ -9,4 +10,4 @@ "SwitchTenant": "تغيير الجهة", "NotSelected": "غير محدد" } -} \ No newline at end of file +} diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy/Volo/Abp/AspNetCore/Mvc/UI/MultiTenancy/Localization/cs.json b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy/Volo/Abp/AspNetCore/Mvc/UI/MultiTenancy/Localization/cs.json index 05457dfa16..0f63728c77 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy/Volo/Abp/AspNetCore/Mvc/UI/MultiTenancy/Localization/cs.json +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy/Volo/Abp/AspNetCore/Mvc/UI/MultiTenancy/Localization/cs.json @@ -1,6 +1,7 @@ { "culture": "cs", "texts": { + "GivenTenantIsNotExist": "Vybraný tenant neexistuje: {0}", "GivenTenantIsNotAvailable": "Zvolený tenant není dostupný: {0}", "Tenant": "Tenant", "Switch": "změnit", diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy/Volo/Abp/AspNetCore/Mvc/UI/MultiTenancy/Localization/de-DE.json b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy/Volo/Abp/AspNetCore/Mvc/UI/MultiTenancy/Localization/de-DE.json index 3b1f12c29d..a0bb43999a 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy/Volo/Abp/AspNetCore/Mvc/UI/MultiTenancy/Localization/de-DE.json +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy/Volo/Abp/AspNetCore/Mvc/UI/MultiTenancy/Localization/de-DE.json @@ -1,6 +1,7 @@ { "culture": "de-DE", "texts": { + "GivenTenantIsNotExist": "Der angegebene Client ist nicht vorhanden: {0}", "GivenTenantIsNotAvailable": "Der angegebene Mandant ist nicht verfügbar: {0}", "Tenant": "Mandant", "Switch": "wechseln", @@ -9,4 +10,4 @@ "SwitchTenant": "Mandant wechseln", "NotSelected": "Nicht ausgewählt" } -} \ No newline at end of file +} diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy/Volo/Abp/AspNetCore/Mvc/UI/MultiTenancy/Localization/de.json b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy/Volo/Abp/AspNetCore/Mvc/UI/MultiTenancy/Localization/de.json index 98909d9847..029e7ed76a 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy/Volo/Abp/AspNetCore/Mvc/UI/MultiTenancy/Localization/de.json +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy/Volo/Abp/AspNetCore/Mvc/UI/MultiTenancy/Localization/de.json @@ -1,6 +1,7 @@ { "culture": "de", "texts": { + "GivenTenantIsNotExist": "Der angegebene Client ist nicht vorhanden: {0}", "GivenTenantIsNotAvailable": "Der angegebene Mandant ist nicht verfügbar: {0}", "Tenant": "Mandant", "Switch": "wechseln", @@ -9,4 +10,4 @@ "SwitchTenant": "Mandant wechseln", "NotSelected": "Nicht ausgewählt" } -} \ No newline at end of file +} diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy/Volo/Abp/AspNetCore/Mvc/UI/MultiTenancy/Localization/en-GB.json b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy/Volo/Abp/AspNetCore/Mvc/UI/MultiTenancy/Localization/en-GB.json index be5593fbd3..e93e7ef25e 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy/Volo/Abp/AspNetCore/Mvc/UI/MultiTenancy/Localization/en-GB.json +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy/Volo/Abp/AspNetCore/Mvc/UI/MultiTenancy/Localization/en-GB.json @@ -1,6 +1,7 @@ { "culture": "en-GB", "texts": { + "GivenTenantIsNotExist": "Given tenant is not exist: {0}", "GivenTenantIsNotAvailable": "Given tenant is not available: {0}", "Tenant": "Tenant", "Switch": "switch", @@ -9,4 +10,4 @@ "SwitchTenant": "Switch tenant", "NotSelected": "Not selected" } -} \ No newline at end of file +} diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy/Volo/Abp/AspNetCore/Mvc/UI/MultiTenancy/Localization/en.json b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy/Volo/Abp/AspNetCore/Mvc/UI/MultiTenancy/Localization/en.json index d1a9f1f09e..25516ba765 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy/Volo/Abp/AspNetCore/Mvc/UI/MultiTenancy/Localization/en.json +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy/Volo/Abp/AspNetCore/Mvc/UI/MultiTenancy/Localization/en.json @@ -1,6 +1,7 @@ { "culture": "en", "texts": { + "GivenTenantIsNotExist": "Given tenant is not exist: {0}", "GivenTenantIsNotAvailable": "Given tenant is not available: {0}", "Tenant": "Tenant", "Switch": "switch", @@ -9,4 +10,4 @@ "SwitchTenant": "Switch tenant", "NotSelected": "Not selected" } -} \ No newline at end of file +} diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy/Volo/Abp/AspNetCore/Mvc/UI/MultiTenancy/Localization/es-mx.json b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy/Volo/Abp/AspNetCore/Mvc/UI/MultiTenancy/Localization/es-mx.json index 746f1dec0f..5cd08ab345 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy/Volo/Abp/AspNetCore/Mvc/UI/MultiTenancy/Localization/es-mx.json +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy/Volo/Abp/AspNetCore/Mvc/UI/MultiTenancy/Localization/es-mx.json @@ -1,6 +1,7 @@ { "culture": "es-MX", "texts": { + "GivenTenantIsNotExist": "El inquilino {0} no existe", "GivenTenantIsNotAvailable": "El inquilino {0} no está disponible", "Tenant": "Inquilino", "Switch": "cambiar", diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy/Volo/Abp/AspNetCore/Mvc/UI/MultiTenancy/Localization/es.json b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy/Volo/Abp/AspNetCore/Mvc/UI/MultiTenancy/Localization/es.json index d6fd84dcbe..bd2d82a2d0 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy/Volo/Abp/AspNetCore/Mvc/UI/MultiTenancy/Localization/es.json +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy/Volo/Abp/AspNetCore/Mvc/UI/MultiTenancy/Localization/es.json @@ -1,6 +1,7 @@ { "culture": "es", "texts": { + "GivenTenantIsNotExist": "El inquilino {0} no existe", "GivenTenantIsNotAvailable": "El inquilino {0} no está disponible", "Tenant": "Inquilino", "Switch": "cambiar", @@ -9,4 +10,4 @@ "SwitchTenantHint": "Deje en blanco el campo nombre para cambiar el lado del host.", "NotSelected": "No seleccionado" } -} \ No newline at end of file +} diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy/Volo/Abp/AspNetCore/Mvc/UI/MultiTenancy/Localization/fi.json b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy/Volo/Abp/AspNetCore/Mvc/UI/MultiTenancy/Localization/fi.json index 7cbeabe8cd..d6fb04eb4c 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy/Volo/Abp/AspNetCore/Mvc/UI/MultiTenancy/Localization/fi.json +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy/Volo/Abp/AspNetCore/Mvc/UI/MultiTenancy/Localization/fi.json @@ -1,6 +1,7 @@ { "culture": "fi", "texts": { + "GivenTenantIsNotExist": "Annettua vuokralaista ei ole olemassa: {0}", "GivenTenantIsNotAvailable": "Annettua vuokralaista ei ole saatavilla: {0}", "Tenant": "Vuokralainen", "Switch": "vaihtaa", @@ -9,4 +10,4 @@ "SwitchTenant": "Vaihda vuokralainen", "NotSelected": "Ei valittu" } -} \ No newline at end of file +} diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy/Volo/Abp/AspNetCore/Mvc/UI/MultiTenancy/Localization/fr.json b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy/Volo/Abp/AspNetCore/Mvc/UI/MultiTenancy/Localization/fr.json index dbd17957fc..6fe00242b5 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy/Volo/Abp/AspNetCore/Mvc/UI/MultiTenancy/Localization/fr.json +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy/Volo/Abp/AspNetCore/Mvc/UI/MultiTenancy/Localization/fr.json @@ -1,6 +1,7 @@ { "culture": "fr", "texts": { + "GivenTenantIsNotExist": "Adott bérlő nem létezik: {0}", "GivenTenantIsNotAvailable": "Le Tenant donné n'est pas disponible: {0}", "Tenant": "Tenant", "Switch": "Changer", @@ -9,4 +10,4 @@ "SwitchTenant": "Changer le Tenant", "NotSelected": "Non séléctionné" } -} \ No newline at end of file +} diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy/Volo/Abp/AspNetCore/Mvc/UI/MultiTenancy/Localization/hi.json b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy/Volo/Abp/AspNetCore/Mvc/UI/MultiTenancy/Localization/hi.json new file mode 100644 index 0000000000..bc1ea195cd --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy/Volo/Abp/AspNetCore/Mvc/UI/MultiTenancy/Localization/hi.json @@ -0,0 +1,13 @@ +{ + "culture": "hi", + "texts": { + "GivenTenantIsNotExist": "किरायेदार मौजूद नहीं है: {0}", + "GivenTenantIsNotAvailable": "उपलब्ध किरायेदार उपलब्ध नहीं है: {0}", + "Tenant": "किरायेदार", + "Switch": "स्विच", + "Name": "नाम", + "SwitchTenantHint": "होस्ट फ़ील्ड पर जाने के लिए नाम फ़ील्ड रिक्त छोड़ें।", + "SwitchTenant": "किरायेदार स्विच करें", + "NotSelected": "नहीं चुने गए" + } +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy/Volo/Abp/AspNetCore/Mvc/UI/MultiTenancy/Localization/hu.json b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy/Volo/Abp/AspNetCore/Mvc/UI/MultiTenancy/Localization/hu.json index 057e9d2968..108b3520d7 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy/Volo/Abp/AspNetCore/Mvc/UI/MultiTenancy/Localization/hu.json +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy/Volo/Abp/AspNetCore/Mvc/UI/MultiTenancy/Localization/hu.json @@ -1,6 +1,7 @@ { "culture": "hu", "texts": { + "GivenTenantIsNotExist": "Adott bérlő nem létezik: {0}", "GivenTenantIsNotAvailable": "A megadott előfizető nem érhető el: {0}", "Tenant": "Előfizető", "Switch": "váltás", @@ -9,4 +10,4 @@ "SwitchTenant": "Előfizető váltás", "NotSelected": "Nincs kiválasztva" } - } \ No newline at end of file + } diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy/Volo/Abp/AspNetCore/Mvc/UI/MultiTenancy/Localization/it.json b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy/Volo/Abp/AspNetCore/Mvc/UI/MultiTenancy/Localization/it.json new file mode 100644 index 0000000000..e46b96fb20 --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy/Volo/Abp/AspNetCore/Mvc/UI/MultiTenancy/Localization/it.json @@ -0,0 +1,13 @@ +{ + "culture": "it", + "texts": { + "GivenTenantIsNotExist": "Il tenant specificato non esiste: {0}", + "GivenTenantIsNotAvailable": "Il tenant specificato non è disponibile: {0}", + "Tenant": "Inquilino", + "Switch": "interruttore", + "Name": "Nome", + "SwitchTenantHint": "Lascia vuoto il campo del nome per passare al lato host.", + "SwitchTenant": "Cambia inquilino", + "NotSelected": "Non selezionato" + } +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy/Volo/Abp/AspNetCore/Mvc/UI/MultiTenancy/Localization/nl.json b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy/Volo/Abp/AspNetCore/Mvc/UI/MultiTenancy/Localization/nl.json index ea15166b9e..3cbb689f03 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy/Volo/Abp/AspNetCore/Mvc/UI/MultiTenancy/Localization/nl.json +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy/Volo/Abp/AspNetCore/Mvc/UI/MultiTenancy/Localization/nl.json @@ -1,6 +1,7 @@ { "culture": "nl", "texts": { + "GivenTenantIsNotExist": "Opgegeven huurder bestaat niet: {0}", "GivenTenantIsNotAvailable": "Gegeven klant is niet beschikbaar: {0}", "Tenant": "Klant", "Switch": "Schakel over", @@ -9,4 +10,4 @@ "SwitchTenant": "Klant wisselen", "NotSelected": "Niet geselecteerd" } -} \ No newline at end of file +} diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy/Volo/Abp/AspNetCore/Mvc/UI/MultiTenancy/Localization/pl-PL.json b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy/Volo/Abp/AspNetCore/Mvc/UI/MultiTenancy/Localization/pl-PL.json index 438d770a7c..79d3e9640d 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy/Volo/Abp/AspNetCore/Mvc/UI/MultiTenancy/Localization/pl-PL.json +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy/Volo/Abp/AspNetCore/Mvc/UI/MultiTenancy/Localization/pl-PL.json @@ -1,6 +1,7 @@ { "culture": "pl-PL", "texts": { + "GivenTenantIsNotExist": "Podany najemca nie istnieje: {0}", "GivenTenantIsNotAvailable": "Podany tenant jest niedostępny: {0}", "Tenant": "Tenant", "Switch": "zmień", @@ -8,4 +9,4 @@ "SwitchTenantHint": "Pozostaw pole nazwy puste, aby przełączyć się na stronę hosta.", "NotSelected": "Nie wybrano" } -} \ No newline at end of file +} diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy/Volo/Abp/AspNetCore/Mvc/UI/MultiTenancy/Localization/pt-BR.json b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy/Volo/Abp/AspNetCore/Mvc/UI/MultiTenancy/Localization/pt-BR.json index 8ac517d594..95396abca1 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy/Volo/Abp/AspNetCore/Mvc/UI/MultiTenancy/Localization/pt-BR.json +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy/Volo/Abp/AspNetCore/Mvc/UI/MultiTenancy/Localization/pt-BR.json @@ -1,6 +1,7 @@ { "culture": "pt-BR", "texts": { + "GivenTenantIsNotExist": "O inquilino dado não existe: {0}", "GivenTenantIsNotAvailable": "Inquilino não está disponível: {0}", "Tenant": "Inquilino", "Switch": "trocar", @@ -9,4 +10,4 @@ "SwitchTenant": "Alterar Inquilino", "NotSelected": "Não selecionado" } -} \ No newline at end of file +} diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy/Volo/Abp/AspNetCore/Mvc/UI/MultiTenancy/Localization/ru.json b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy/Volo/Abp/AspNetCore/Mvc/UI/MultiTenancy/Localization/ru.json index 04b2e5cf85..5492a7d7bb 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy/Volo/Abp/AspNetCore/Mvc/UI/MultiTenancy/Localization/ru.json +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy/Volo/Abp/AspNetCore/Mvc/UI/MultiTenancy/Localization/ru.json @@ -1,6 +1,7 @@ { "culture": "ru", "texts": { + "GivenTenantIsNotExist": "Данный арендатор не существует: {0}", "GivenTenantIsNotAvailable": "Данный арендатор недоступен: {0}", "Tenant": "Арендатор", "Switch": "переключиться", diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy/Volo/Abp/AspNetCore/Mvc/UI/MultiTenancy/Localization/sl.json b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy/Volo/Abp/AspNetCore/Mvc/UI/MultiTenancy/Localization/sl.json index 51938a569e..b1a07d3ee9 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy/Volo/Abp/AspNetCore/Mvc/UI/MultiTenancy/Localization/sl.json +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy/Volo/Abp/AspNetCore/Mvc/UI/MultiTenancy/Localization/sl.json @@ -1,6 +1,7 @@ { "culture": "sl", "texts": { + "GivenTenantIsNotExist": "Dani najemnik ne obstaja: {0}", "GivenTenantIsNotAvailable": "Najemnik ni na voljo: {0}", "Tenant": "Najemnik", "Switch": "Zamenjaj", diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy/Volo/Abp/AspNetCore/Mvc/UI/MultiTenancy/Localization/tr.json b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy/Volo/Abp/AspNetCore/Mvc/UI/MultiTenancy/Localization/tr.json index 994579e934..b5b6c374c1 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy/Volo/Abp/AspNetCore/Mvc/UI/MultiTenancy/Localization/tr.json +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy/Volo/Abp/AspNetCore/Mvc/UI/MultiTenancy/Localization/tr.json @@ -1,6 +1,7 @@ { "culture": "tr", "texts": { + "GivenTenantIsNotExist": "İstenilen müşteri bulunamadı: {0}", "GivenTenantIsNotAvailable": "İstenilen müşteri bulunamadı: {0}", "Tenant": "Müşteri", "Switch": "değiştir", @@ -9,4 +10,4 @@ "SwitchTenant": "Müşteri değiştir", "NotSelected": "Seçili değil" } -} \ No newline at end of file +} diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy/Volo/Abp/AspNetCore/Mvc/UI/MultiTenancy/Localization/vi.json b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy/Volo/Abp/AspNetCore/Mvc/UI/MultiTenancy/Localization/vi.json index 975e1b4590..b8ad08bb82 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy/Volo/Abp/AspNetCore/Mvc/UI/MultiTenancy/Localization/vi.json +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy/Volo/Abp/AspNetCore/Mvc/UI/MultiTenancy/Localization/vi.json @@ -1,6 +1,7 @@ { "culture": "vi", "texts": { + "GivenTenantIsNotExist": "Người thuê đã cho không tồn tại: {0}", "GivenTenantIsNotAvailable": "Người thuê không có sẵn: {0}", "Tenant": "Người thuê", "Switch": "Chuyển đổi", diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy/Volo/Abp/AspNetCore/Mvc/UI/MultiTenancy/Localization/zh-Hans.json b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy/Volo/Abp/AspNetCore/Mvc/UI/MultiTenancy/Localization/zh-Hans.json index 31588cbebd..0e86d66293 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy/Volo/Abp/AspNetCore/Mvc/UI/MultiTenancy/Localization/zh-Hans.json +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy/Volo/Abp/AspNetCore/Mvc/UI/MultiTenancy/Localization/zh-Hans.json @@ -1,6 +1,7 @@ { "culture": "zh-Hans", "texts": { + "GivenTenantIsNotExist": "给定的租户不存在: {0}", "GivenTenantIsNotAvailable": "给定的租户不可用: {0}", "Tenant": "租户", "Switch": "切换", @@ -9,4 +10,4 @@ "SwitchTenant": "切换租户", "NotSelected": "未选中" } - } \ No newline at end of file + } diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy/Volo/Abp/AspNetCore/Mvc/UI/MultiTenancy/Localization/zh-Hant.json b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy/Volo/Abp/AspNetCore/Mvc/UI/MultiTenancy/Localization/zh-Hant.json index 12eea67007..10a0da1023 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy/Volo/Abp/AspNetCore/Mvc/UI/MultiTenancy/Localization/zh-Hant.json +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy/Volo/Abp/AspNetCore/Mvc/UI/MultiTenancy/Localization/zh-Hant.json @@ -1,6 +1,7 @@ { "culture": "zh-Hant", "texts": { + "GivenTenantIsNotExist": "指定的租戶不存在: {0}", "GivenTenantIsNotAvailable": "指定的租戶不可用: {0}", "SwitchTenant": "切換租戶", "Name": "名稱", @@ -9,4 +10,4 @@ "Switch": "切換", "NotSelected": "尚未選定" } -} \ No newline at end of file +} diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared/Toolbars/ToolbarItem.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared/Toolbars/ToolbarItem.cs index 4676202c24..f7cba501c3 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared/Toolbars/ToolbarItem.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared/Toolbars/ToolbarItem.cs @@ -1,9 +1,11 @@ using System; +using System.Collections.Generic; using JetBrains.Annotations; +using Volo.Abp.SimpleStateChecking; namespace Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Toolbars { - public class ToolbarItem + public class ToolbarItem : IHasSimpleStateCheckers { public Type ComponentType { @@ -15,13 +17,17 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Toolbars public int Order { get; set; } [CanBeNull] + [Obsolete("Use RequirePermissions extension method.")] public string RequiredPermissionName { get; set; } + public List> StateCheckers { get; } + public ToolbarItem([NotNull] Type componentType, int order = 0, string requiredPermissionName = null) { Order = order; ComponentType = Check.NotNull(componentType, nameof(componentType)); RequiredPermissionName = requiredPermissionName; + StateCheckers = new List>(); } } } diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared/Toolbars/ToolbarManager.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared/Toolbars/ToolbarManager.cs index 2e97cebecb..53679c5b22 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared/Toolbars/ToolbarManager.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared/Toolbars/ToolbarManager.cs @@ -7,6 +7,7 @@ using Microsoft.Extensions.Options; using Volo.Abp.AspNetCore.Mvc.UI.Theming; using Volo.Abp.Authorization.Permissions; using Volo.Abp.DependencyInjection; +using Volo.Abp.SimpleStateChecking; namespace Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Toolbars { @@ -15,13 +16,16 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Toolbars protected IThemeManager ThemeManager { get; } protected AbpToolbarOptions Options { get; } protected IServiceProvider ServiceProvider { get; } + protected ISimpleStateCheckerManager SimpleStateCheckerManager { get; } public ToolbarManager( IOptions options, IServiceProvider serviceProvider, - IThemeManager themeManager) + IThemeManager themeManager, + ISimpleStateCheckerManager simpleStateCheckerManager) { ThemeManager = themeManager; + SimpleStateCheckerManager = simpleStateCheckerManager; ServiceProvider = serviceProvider; Options = options.Value; } @@ -32,14 +36,17 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Toolbars using (var scope = ServiceProvider.CreateScope()) { - var context = new ToolbarConfigurationContext(ThemeManager.CurrentTheme, toolbar, scope.ServiceProvider); - - foreach (var contributor in Options.Contributors) + using (RequirePermissionsSimpleBatchStateChecker.Use(new RequirePermissionsSimpleBatchStateChecker())) { - await contributor.ConfigureToolbarAsync(context); - } + var context = new ToolbarConfigurationContext(ThemeManager.CurrentTheme, toolbar, scope.ServiceProvider); + + foreach (var contributor in Options.Contributors) + { + await contributor.ConfigureToolbarAsync(context); + } - await CheckPermissionsAsync(scope.ServiceProvider, toolbar); + await CheckPermissionsAsync(scope.ServiceProvider, toolbar); + } } return toolbar; @@ -47,17 +54,20 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Toolbars protected virtual async Task CheckPermissionsAsync(IServiceProvider serviceProvider, Toolbar toolbar) { - var requiredPermissionItems = toolbar.Items.Where(x => !x.RequiredPermissionName.IsNullOrWhiteSpace()).ToList(); + foreach (var item in toolbar.Items.Where(x => !x.RequiredPermissionName.IsNullOrWhiteSpace())) + { + item.RequirePermissions(item.RequiredPermissionName); + } - if (requiredPermissionItems.Any()) + var checkPermissionsToolbarItems = toolbar.Items.Where(x => x.StateCheckers.Any()).ToArray(); + if (checkPermissionsToolbarItems.Any()) { - var permissionChecker = serviceProvider.GetRequiredService(); - var grantResult = await permissionChecker.IsGrantedAsync(requiredPermissionItems.Select(x => x.RequiredPermissionName).Distinct().ToArray()); + var result = await SimpleStateCheckerManager.IsEnabledAsync(checkPermissionsToolbarItems); var toBeDeleted = new HashSet(); - foreach (var item in requiredPermissionItems) + foreach (var item in checkPermissionsToolbarItems) { - if (grantResult.Result[item.RequiredPermissionName!] != PermissionGrantResult.Granted) + if (!result[item]) { toBeDeleted.Add(item); } diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ModelBinding/AbpDateTimeModelBinder.cs b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ModelBinding/AbpDateTimeModelBinder.cs index 1916b9aa16..cf2203a8e9 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ModelBinding/AbpDateTimeModelBinder.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ModelBinding/AbpDateTimeModelBinder.cs @@ -2,48 +2,28 @@ using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc.ModelBinding; using Microsoft.AspNetCore.Mvc.ModelBinding.Binders; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Logging; using Volo.Abp.Timing; namespace Volo.Abp.AspNetCore.Mvc.ModelBinding { public class AbpDateTimeModelBinder : IModelBinder { - private readonly Type _type; - private readonly SimpleTypeModelBinder _simpleTypeModelBinder; + private readonly DateTimeModelBinder _dateTimeModelBinder; private readonly IClock _clock; - public AbpDateTimeModelBinder(ModelBinderProviderContext context) + public AbpDateTimeModelBinder(IClock clock, DateTimeModelBinder dateTimeModelBinder) { - _type = context.Metadata.ModelType; - _clock = context.Services.GetRequiredService(); - _simpleTypeModelBinder = new SimpleTypeModelBinder(context.Metadata.ModelType, - context.Services.GetRequiredService()); + _clock = clock; + _dateTimeModelBinder = dateTimeModelBinder; } public async Task BindModelAsync(ModelBindingContext bindingContext) { - await _simpleTypeModelBinder.BindModelAsync(bindingContext); - - if (!bindingContext.Result.IsModelSet) - { - return; - } - - if (_type == typeof(DateTime)) + await _dateTimeModelBinder.BindModelAsync(bindingContext); + if (bindingContext.Result.IsModelSet && bindingContext.Result.Model is DateTime dateTime) { - var dateTime = (DateTime) bindingContext.Result.Model; bindingContext.Result = ModelBindingResult.Success(_clock.Normalize(dateTime)); } - else - { - var dateTime = (DateTime?) bindingContext.Result.Model; - if (dateTime != null) - { - bindingContext.Result = ModelBindingResult.Success(_clock.Normalize(dateTime.Value)); - } - } } } -} \ No newline at end of file +} diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ModelBinding/AbpDateTimeModelBinderProvider.cs b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ModelBinding/AbpDateTimeModelBinderProvider.cs index ddda91c8a0..83129199bc 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ModelBinding/AbpDateTimeModelBinderProvider.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ModelBinding/AbpDateTimeModelBinderProvider.cs @@ -1,48 +1,56 @@ using System; +using System.Globalization; using System.Linq; using Microsoft.AspNetCore.Mvc.ModelBinding; +using Microsoft.AspNetCore.Mvc.ModelBinding.Binders; using Microsoft.AspNetCore.Mvc.ModelBinding.Metadata; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging; using Volo.Abp.Timing; namespace Volo.Abp.AspNetCore.Mvc.ModelBinding { - public class AbpDateTimeModelBinderProvider : IModelBinderProvider { public IModelBinder GetBinder(ModelBinderProviderContext context) { - if (context.Metadata.ModelType != typeof(DateTime) && - context.Metadata.ModelType != typeof(DateTime?)) - { - return null; - } - - if (context.Metadata.ContainerType == null) + var modelType = context.Metadata.UnderlyingOrModelType; + if (modelType == typeof(DateTime)) { - if (context.Metadata is DefaultModelMetadata defaultModelMetadata && - defaultModelMetadata.Attributes.Attributes.All(x => x.GetType() != typeof(DisableDateTimeNormalizationAttribute))) + if (context.Metadata.ContainerType == null) { - return new AbpDateTimeModelBinder(context); + if (context.Metadata is DefaultModelMetadata defaultModelMetadata && + defaultModelMetadata.Attributes.Attributes.All(x => x.GetType() != typeof(DisableDateTimeNormalizationAttribute))) + { + return CreateAbpDateTimeModelBinder(context); + } } - } - else - { - var dateNormalizationDisabledForClass = - context.Metadata.ContainerType.IsDefined(typeof(DisableDateTimeNormalizationAttribute), true); + else + { + var dateNormalizationDisabledForClass = + context.Metadata.ContainerType.IsDefined(typeof(DisableDateTimeNormalizationAttribute), true); - var dateNormalizationDisabledForProperty = context.Metadata.ContainerType - .GetProperty(context.Metadata.PropertyName) - ?.IsDefined(typeof(DisableDateTimeNormalizationAttribute), true); + var dateNormalizationDisabledForProperty = context.Metadata.ContainerType + .GetProperty(context.Metadata.PropertyName) + ?.IsDefined(typeof(DisableDateTimeNormalizationAttribute), true); - if (!dateNormalizationDisabledForClass && - dateNormalizationDisabledForProperty != null && - !dateNormalizationDisabledForProperty.Value) - { - return new AbpDateTimeModelBinder(context); + if (!dateNormalizationDisabledForClass && + dateNormalizationDisabledForProperty != null && + !dateNormalizationDisabledForProperty.Value) + { + return CreateAbpDateTimeModelBinder(context); + } } } return null; } + + protected virtual AbpDateTimeModelBinder CreateAbpDateTimeModelBinder(ModelBinderProviderContext context) + { + const DateTimeStyles supportedStyles = DateTimeStyles.AllowWhiteSpaces | DateTimeStyles.AdjustToUniversal; + var dateTimeModelBinder = new DateTimeModelBinder(supportedStyles, context.Services.GetRequiredService()); + return new AbpDateTimeModelBinder(context.Services.GetRequiredService(), dateTimeModelBinder); + } } } diff --git a/framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/AbpPermissionOptions.cs b/framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/AbpPermissionOptions.cs index eb2ac920ac..ce9dc06798 100644 --- a/framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/AbpPermissionOptions.cs +++ b/framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/AbpPermissionOptions.cs @@ -8,13 +8,10 @@ namespace Volo.Abp.Authorization.Permissions public ITypeList ValueProviders { get; } - public ITypeList GlobalStateProviders { get; } - public AbpPermissionOptions() { DefinitionProviders = new TypeList(); ValueProviders = new TypeList(); - GlobalStateProviders = new TypeList(); } } } diff --git a/framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/IPermissionStateManager.cs b/framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/IPermissionStateManager.cs deleted file mode 100644 index 6195e02545..0000000000 --- a/framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/IPermissionStateManager.cs +++ /dev/null @@ -1,9 +0,0 @@ -using System.Threading.Tasks; - -namespace Volo.Abp.Authorization.Permissions -{ - public interface IPermissionStateManager - { - Task IsEnabledAsync(PermissionDefinition permission); - } -} diff --git a/framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/IPermissionStateProvider.cs b/framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/IPermissionStateProvider.cs deleted file mode 100644 index 7bc3087f50..0000000000 --- a/framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/IPermissionStateProvider.cs +++ /dev/null @@ -1,9 +0,0 @@ -using System.Threading.Tasks; - -namespace Volo.Abp.Authorization.Permissions -{ - public interface IPermissionStateProvider - { - Task IsEnabledAsync(PermissionStateContext context); - } -} diff --git a/framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/PermissionDefinition.cs b/framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/PermissionDefinition.cs index ac525367ad..92eda28b4b 100644 --- a/framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/PermissionDefinition.cs +++ b/framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/PermissionDefinition.cs @@ -3,10 +3,11 @@ using System.Collections.Immutable; using JetBrains.Annotations; using Volo.Abp.Localization; using Volo.Abp.MultiTenancy; +using Volo.Abp.SimpleStateChecking; namespace Volo.Abp.Authorization.Permissions { - public class PermissionDefinition + public class PermissionDefinition : IHasSimpleStateCheckers { /// /// Unique name of the permission. @@ -31,7 +32,7 @@ namespace Volo.Abp.Authorization.Permissions /// public List Providers { get; } //TODO: Rename to AllowedProviders? - public List StateProviders { get; } + public List> StateCheckers { get; } public ILocalizableString DisplayName { @@ -88,7 +89,7 @@ namespace Volo.Abp.Authorization.Permissions Properties = new Dictionary(); Providers = new List(); - StateProviders = new List(); + StateCheckers = new List>(); _children = new List(); } @@ -123,7 +124,7 @@ namespace Volo.Abp.Authorization.Permissions } /// - /// Sets a property in the dictionary. + /// Set the property. /// This is a shortcut for nested calls on this object. /// public virtual PermissionDefinition WithProviders(params string[] providers) diff --git a/framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/PermissionDefinitionExtensions.cs b/framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/PermissionDefinitionExtensions.cs deleted file mode 100644 index 7e5de5a1f1..0000000000 --- a/framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/PermissionDefinitionExtensions.cs +++ /dev/null @@ -1,19 +0,0 @@ -using JetBrains.Annotations; - -namespace Volo.Abp.Authorization.Permissions -{ - public static class PermissionDefinitionExtensions - { - public static PermissionDefinition AddStateProviders( - [NotNull] this PermissionDefinition permissionDefinition, - [NotNull] params IPermissionStateProvider[] permissionStateProviders) - { - Check.NotNull(permissionDefinition, nameof(permissionDefinition)); - Check.NotNull(permissionStateProviders, nameof(permissionStateProviders)); - - permissionDefinition.StateProviders.AddRange(permissionStateProviders); - - return permissionDefinition; - } - } -} diff --git a/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Localization/FR.json b/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Localization/fr.json similarity index 84% rename from framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Localization/FR.json rename to framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Localization/fr.json index 7626604b93..02ab735f7b 100644 --- a/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Localization/FR.json +++ b/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Localization/fr.json @@ -1,8 +1,8 @@ { "culture": "fr", "texts": { - "Volo.Authorization:010001": "L'autorisation à échouée! Compte tenu de la politique n'a pas accordé.", - "Volo.Authorization:010002": "L'autorisation à échouée! La politique donnée n'a pas accordé: {PolicyName}", + "Volo.Authorization:010001": "L'autorisation à échouée! Compte tenu de la stratégie n'a été pas accordé.", + "Volo.Authorization:010002": "L'autorisation à échouée! La stratégie donnée n'a pas été accordé: {PolicyName}", "Volo.Authorization:010003": "L'autorisation à échouée! La stratégie donnée n'a pas été accordée pour une ressource donnée: {ResourceName}", "Volo.Authorization:010004": "L'autorisation à échouée! L'exigence donnée n'a pas été accordée pour une ressource donnée: {ResourceName}", "Volo.Authorization:010005": "L'autorisation à échouée! Les exigences données ne sont pas accordées pour une ressource donnée: {ResourceName}" diff --git a/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Localization/hi.json b/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Localization/hi.json new file mode 100644 index 0000000000..ee999ca075 --- /dev/null +++ b/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Localization/hi.json @@ -0,0 +1,10 @@ +{ + "culture": "hi", + "texts": { + "Volo.Authorization:010001": "प्रमाणीकरण विफल! दी गई नीति को अनुमति नहीं दी गई है।", + "Volo.Authorization:010002": "प्रमाणीकरण विफल! दी गई नीति को मंजूरी नहीं दी गई है: {PolicyName}", + "Volo.Authorization:010003": "प्रमाणीकरण विफल! दिए गए संसाधन के लिए नीति प्रदान नहीं की गई है: {ResourceName}", + "Volo.Authorization:010004": "प्रमाणीकरण विफल! दिए गए संसाधन के लिए आवश्यकता की अनुमति नहीं दी गई है: {ResourceName}", + "Volo.Authorization:010005": "प्रमाणीकरण विफल! दी गई संसाधन के लिए आवश्यकताओं को पूरा नहीं किया गया है: {ResourceName}" + } +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Localization/it.json b/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Localization/it.json new file mode 100644 index 0000000000..422458c820 --- /dev/null +++ b/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Localization/it.json @@ -0,0 +1,10 @@ +{ + "culture": "it", + "texts": { + "Volo.Authorization:010001": "Autorizzazione fallita! Data la politica non ha concesso.", + "Volo.Authorization:010002": "Autorizzazione fallita! La norma data non ha concesso: {PolicyName}", + "Volo.Authorization:010003": "Autorizzazione fallita! La politica data non è stata concessa per una determinata risorsa: {ResourceName}", + "Volo.Authorization:010004": "Autorizzazione fallita! Il requisito dato non è stato concesso per la risorsa data: {ResourceName}", + "Volo.Authorization:010005": "Autorizzazione fallita! I requisiti dati non sono stati concessi per una determinata risorsa: {ResourceName}" + } +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/PermissionChecker.cs b/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/PermissionChecker.cs index d243c9c54c..234fbf7ea2 100644 --- a/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/PermissionChecker.cs +++ b/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/PermissionChecker.cs @@ -6,6 +6,7 @@ using System.Threading.Tasks; using Volo.Abp.DependencyInjection; using Volo.Abp.MultiTenancy; using Volo.Abp.Security.Claims; +using Volo.Abp.SimpleStateChecking; namespace Volo.Abp.Authorization.Permissions { @@ -15,20 +16,20 @@ namespace Volo.Abp.Authorization.Permissions protected ICurrentPrincipalAccessor PrincipalAccessor { get; } protected ICurrentTenant CurrentTenant { get; } protected IPermissionValueProviderManager PermissionValueProviderManager { get; } - protected IPermissionStateManager PermissionStateManager { get; } + protected ISimpleStateCheckerManager StateCheckerManager { get; } public PermissionChecker( ICurrentPrincipalAccessor principalAccessor, IPermissionDefinitionManager permissionDefinitionManager, ICurrentTenant currentTenant, IPermissionValueProviderManager permissionValueProviderManager, - IPermissionStateManager permissionStateManager) + ISimpleStateCheckerManager stateCheckerManager) { PrincipalAccessor = principalAccessor; PermissionDefinitionManager = permissionDefinitionManager; CurrentTenant = currentTenant; PermissionValueProviderManager = permissionValueProviderManager; - PermissionStateManager = permissionStateManager; + StateCheckerManager = stateCheckerManager; } public virtual async Task IsGrantedAsync(string name) @@ -49,7 +50,7 @@ namespace Volo.Abp.Authorization.Permissions return false; } - if (!await PermissionStateManager.IsEnabledAsync(permission)) + if (!await StateCheckerManager.IsEnabledAsync(permission)) { return false; } @@ -112,7 +113,7 @@ namespace Volo.Abp.Authorization.Permissions result.Result.Add(name, PermissionGrantResult.Undefined); if (permission.IsEnabled && - await PermissionStateManager.IsEnabledAsync(permission) && + await StateCheckerManager.IsEnabledAsync(permission) && permission.MultiTenancySide.HasFlag(multiTenancySide)) { permissionDefinitions.Add(permission); diff --git a/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/PermissionSimpleStateCheckerExtensions.cs b/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/PermissionSimpleStateCheckerExtensions.cs new file mode 100644 index 0000000000..c8c4d315fd --- /dev/null +++ b/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/PermissionSimpleStateCheckerExtensions.cs @@ -0,0 +1,57 @@ +using JetBrains.Annotations; +using Volo.Abp.SimpleStateChecking; + +namespace Volo.Abp.Authorization.Permissions +{ + public static class PermissionSimpleStateCheckerExtensions + { + public static TState RequireAuthenticated([NotNull] this TState state) + where TState : IHasSimpleStateCheckers + { + state.StateCheckers.Add(new RequireAuthenticatedSimpleStateChecker()); + return state; + } + + public static TState RequirePermissions( + [NotNull] this TState state, + params string[] permissions) + where TState : IHasSimpleStateCheckers + { + state.RequirePermissions(requiresAll: true, batchCheck: true, permissions); + return state; + } + + public static TState RequirePermissions( + [NotNull] this TState state, + bool requiresAll, + params string[] permissions) + where TState : IHasSimpleStateCheckers + { + state.RequirePermissions(requiresAll: requiresAll, batchCheck: true, permissions); + return state; + } + + public static TState RequirePermissions( + [NotNull] this TState state, + bool requiresAll, + bool batchCheck, + params string[] permissions) + where TState : IHasSimpleStateCheckers + { + Check.NotNull(state, nameof(state)); + Check.NotNullOrEmpty(permissions, nameof(permissions)); + + if (batchCheck) + { + RequirePermissionsSimpleBatchStateChecker.Current.AddCheckModels(new RequirePermissionsSimpleBatchStateCheckerModel(state, permissions, requiresAll)); + state.StateCheckers.Add(RequirePermissionsSimpleBatchStateChecker.Current); + } + else + { + state.StateCheckers.Add(new RequirePermissionsSimpleStateChecker(new RequirePermissionsSimpleBatchStateCheckerModel(state, permissions, requiresAll))); + } + + return state; + } + } +} diff --git a/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/PermissionStateManager.cs b/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/PermissionStateManager.cs deleted file mode 100644 index 957ed3c7a6..0000000000 --- a/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/PermissionStateManager.cs +++ /dev/null @@ -1,51 +0,0 @@ -using System; -using System.Linq; -using System.Threading.Tasks; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Options; -using Volo.Abp.DependencyInjection; - -namespace Volo.Abp.Authorization.Permissions -{ - public class PermissionStateManager : IPermissionStateManager, ITransientDependency - { - protected IServiceProvider ServiceProvider { get; } - protected AbpPermissionOptions Options { get; } - - public PermissionStateManager(IServiceProvider serviceProvider, IOptions options) - { - ServiceProvider = serviceProvider; - Options = options.Value; - } - - public async Task IsEnabledAsync(PermissionDefinition permission) - { - using (var scope = ServiceProvider.CreateScope()) - { - var context = new PermissionStateContext - { - Permission = permission, - ServiceProvider = scope.ServiceProvider.GetRequiredService() - }; - - foreach (var provider in permission.StateProviders) - { - if (!await provider.IsEnabledAsync(context)) - { - return false; - } - } - - foreach (IPermissionStateProvider provider in Options.GlobalStateProviders.Select(x => ServiceProvider.GetRequiredService(x))) - { - if (!await provider.IsEnabledAsync(context)) - { - return false; - } - } - - return true; - } - } - } -} diff --git a/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/RequireAuthenticatedSimpleStateChecker.cs b/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/RequireAuthenticatedSimpleStateChecker.cs new file mode 100644 index 0000000000..64350bd825 --- /dev/null +++ b/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/RequireAuthenticatedSimpleStateChecker.cs @@ -0,0 +1,16 @@ +using System.Threading.Tasks; +using Microsoft.Extensions.DependencyInjection; +using Volo.Abp.SimpleStateChecking; +using Volo.Abp.Users; + +namespace Volo.Abp.Authorization.Permissions +{ + public class RequireAuthenticatedSimpleStateChecker : ISimpleStateChecker + where TState : IHasSimpleStateCheckers + { + public Task IsEnabledAsync(SimpleStateCheckerContext context) + { + return Task.FromResult(context.ServiceProvider.GetRequiredService().IsAuthenticated); + } + } +} diff --git a/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/RequirePermissionsSimpleBatchStateChecker.cs b/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/RequirePermissionsSimpleBatchStateChecker.cs new file mode 100644 index 0000000000..e03b2b87e3 --- /dev/null +++ b/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/RequirePermissionsSimpleBatchStateChecker.cs @@ -0,0 +1,72 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; +using Microsoft.Extensions.DependencyInjection; +using Volo.Abp.SimpleStateChecking; + +namespace Volo.Abp.Authorization.Permissions +{ + public class RequirePermissionsSimpleBatchStateChecker : SimpleBatchStateCheckerBase + where TState : IHasSimpleStateCheckers + { + public static RequirePermissionsSimpleBatchStateChecker Current => _current.Value; + private static readonly AsyncLocal> _current = new AsyncLocal>(); + + private readonly List> _models; + + static RequirePermissionsSimpleBatchStateChecker() + { + _current.Value = new RequirePermissionsSimpleBatchStateChecker(); + } + + public RequirePermissionsSimpleBatchStateChecker() + { + _models = new List>(); + } + + public RequirePermissionsSimpleBatchStateChecker AddCheckModels(params RequirePermissionsSimpleBatchStateCheckerModel[] models) + { + Check.NotNullOrEmpty(models, nameof(models)); + + _models.AddRange(models); + return this; + } + + public static IDisposable Use(RequirePermissionsSimpleBatchStateChecker checker) + { + var previousValue = Current; + _current.Value = checker; + return new DisposeAction(() => _current.Value = previousValue); + } + + public override async Task> IsEnabledAsync(SimpleBatchStateCheckerContext context) + { + var permissionChecker = context.ServiceProvider.GetRequiredService(); + + var result = new SimpleStateCheckerResult(context.States); + + var permissions = _models.Where(x => context.States.Any(s => s.Equals(x.State))).SelectMany(x => x.Permissions).Distinct().ToArray(); + var grantResult = await permissionChecker.IsGrantedAsync(permissions); + + foreach (var state in context.States) + { + var model = _models.FirstOrDefault(x => x.State.Equals(state)); + if (model != null) + { + if (model.RequiresAll) + { + result[model.State] = model.Permissions.All(x => grantResult.Result.Any(y => y.Key == x && y.Value == PermissionGrantResult.Granted)); + } + else + { + result[model.State] = grantResult.Result.Any(x => model.Permissions.Contains(x.Key) && x.Value == PermissionGrantResult.Granted); + } + } + } + + return result; + } + } +} diff --git a/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/RequirePermissionsSimpleBatchStateCheckerModel.cs b/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/RequirePermissionsSimpleBatchStateCheckerModel.cs new file mode 100644 index 0000000000..3660d10f46 --- /dev/null +++ b/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/RequirePermissionsSimpleBatchStateCheckerModel.cs @@ -0,0 +1,24 @@ +using Volo.Abp.SimpleStateChecking; + +namespace Volo.Abp.Authorization.Permissions +{ + public class RequirePermissionsSimpleBatchStateCheckerModel + where TState : IHasSimpleStateCheckers + { + public TState State { get; } + + public string[] Permissions { get; } + + public bool RequiresAll { get; } + + public RequirePermissionsSimpleBatchStateCheckerModel(TState state, string[] permissions, bool requiresAll = true) + { + Check.NotNull(state, nameof(state)); + Check.NotNullOrEmpty(permissions, nameof(permissions)); + + State = state; + Permissions = permissions; + RequiresAll = requiresAll; + } + } +} diff --git a/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/RequirePermissionsSimpleStateChecker.cs b/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/RequirePermissionsSimpleStateChecker.cs new file mode 100644 index 0000000000..32cedeecc6 --- /dev/null +++ b/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/RequirePermissionsSimpleStateChecker.cs @@ -0,0 +1,34 @@ +using System.Linq; +using System.Threading.Tasks; +using Microsoft.Extensions.DependencyInjection; +using Volo.Abp.SimpleStateChecking; + +namespace Volo.Abp.Authorization.Permissions +{ + public class RequirePermissionsSimpleStateChecker : ISimpleStateChecker + where TState : IHasSimpleStateCheckers + { + private readonly RequirePermissionsSimpleBatchStateCheckerModel _model; + + public RequirePermissionsSimpleStateChecker(RequirePermissionsSimpleBatchStateCheckerModel model) + { + _model = model; + } + + public async Task IsEnabledAsync(SimpleStateCheckerContext context) + { + var permissionChecker = context.ServiceProvider.GetRequiredService(); + + if (_model.Permissions.Length == 1) + { + return await permissionChecker.IsGrantedAsync(_model.Permissions.First()); + } + + var grantResult = await permissionChecker.IsGrantedAsync(_model.Permissions); + + return _model.RequiresAll + ? grantResult.AllGranted + : grantResult.Result.Any(x => _model.Permissions.Contains(x.Key) && x.Value == PermissionGrantResult.Granted); + } + } +} diff --git a/framework/src/Volo.Abp.Autofac/Autofac/Builder/AbpRegistrationBuilderExtensions.cs b/framework/src/Volo.Abp.Autofac/Autofac/Builder/AbpRegistrationBuilderExtensions.cs index 96caf956b1..776a8b9a7a 100644 --- a/framework/src/Volo.Abp.Autofac/Autofac/Builder/AbpRegistrationBuilderExtensions.cs +++ b/framework/src/Volo.Abp.Autofac/Autofac/Builder/AbpRegistrationBuilderExtensions.cs @@ -35,7 +35,11 @@ namespace Autofac.Builder return registrationBuilder; } - private static IRegistrationBuilder InvokeRegistrationActions(this IRegistrationBuilder registrationBuilder, ServiceRegistrationActionList registrationActionList, Type serviceType, Type implementationType) + private static IRegistrationBuilder InvokeRegistrationActions( + this IRegistrationBuilder registrationBuilder, + ServiceRegistrationActionList registrationActionList, + Type serviceType, + Type implementationType) where TActivatorData : ReflectionActivatorData { var serviceRegistredArgs = new OnServiceRegistredContext(serviceType, implementationType); @@ -48,6 +52,7 @@ namespace Autofac.Builder if (serviceRegistredArgs.Interceptors.Any()) { registrationBuilder = registrationBuilder.AddInterceptors( + registrationActionList, serviceType, serviceRegistredArgs.Interceptors ); @@ -71,10 +76,12 @@ namespace Autofac.Builder return registrationBuilder; } - private static IRegistrationBuilder AddInterceptors( - this IRegistrationBuilder registrationBuilder, - Type serviceType, - IEnumerable interceptors) + private static IRegistrationBuilder + AddInterceptors( + this IRegistrationBuilder registrationBuilder, + ServiceRegistrationActionList serviceRegistrationActionList, + Type serviceType, + IEnumerable interceptors) where TActivatorData : ReflectionActivatorData { if (serviceType.IsInterface) @@ -83,6 +90,11 @@ namespace Autofac.Builder } else { + if (serviceRegistrationActionList.IsClassInterceptorsDisabled) + { + return registrationBuilder; + } + (registrationBuilder as IRegistrationBuilder)?.EnableClassInterceptors(); } diff --git a/framework/src/Volo.Abp.BlazoriseUI/AbpCrudPageBase.cs b/framework/src/Volo.Abp.BlazoriseUI/AbpCrudPageBase.cs index 6ce4a10a53..19ace62aca 100644 --- a/framework/src/Volo.Abp.BlazoriseUI/AbpCrudPageBase.cs +++ b/framework/src/Volo.Abp.BlazoriseUI/AbpCrudPageBase.cs @@ -485,16 +485,26 @@ namespace Volo.Abp.BlazoriseUI try { await CheckDeletePolicyAsync(); - + await OnDeletingEntityAsync(); await AppService.DeleteAsync(entity.Id); - await GetEntitiesAsync(); - await InvokeAsync(StateHasChanged); + await OnDeletedEntityAsync(); } catch (Exception ex) { await HandleErrorAsync(ex); } } + + protected virtual Task OnDeletingEntityAsync() + { + return Task.CompletedTask; + } + + protected virtual async Task OnDeletedEntityAsync() + { + await GetEntitiesAsync(); + await InvokeAsync(StateHasChanged); + } protected virtual string GetDeleteConfirmationMessage(TListViewModel entity) { diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/AbpCliCoreModule.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/AbpCliCoreModule.cs index 330cbeb77a..ce6ab1e831 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/AbpCliCoreModule.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/AbpCliCoreModule.cs @@ -36,6 +36,7 @@ namespace Volo.Abp.Cli options.Commands["add-module"] = typeof(AddModuleCommand); options.Commands["list-modules"] = typeof(ListModulesCommand); options.Commands["login"] = typeof(LoginCommand); + options.Commands["login-info"] = typeof(LoginInfoCommand); options.Commands["logout"] = typeof(LogoutCommand); options.Commands[GenerateProxyCommand.Name] = typeof(GenerateProxyCommand); options.Commands[RemoveProxyCommand.Name] = typeof(RemoveProxyCommand); diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Args/CommandLineArgumentParser.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Args/CommandLineArgumentParser.cs index 1dd29e5df7..b7cd95a3e0 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Args/CommandLineArgumentParser.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Args/CommandLineArgumentParser.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Text; using Volo.Abp.DependencyInjection; namespace Volo.Abp.Cli.Args @@ -71,6 +72,11 @@ namespace Volo.Abp.Cli.Args return commandLineArgs; } + public CommandLineArgs Parse(string lineText) + { + return Parse(GetArgsArrayFromLine(lineText)); + } + private static bool IsOptionName(string argument) { return argument.StartsWith("-") || argument.StartsWith("--"); @@ -100,5 +106,46 @@ namespace Volo.Abp.Cli.Args throw new ArgumentException("Option names should start with '-' or '--'."); } + + private static string[] GetArgsArrayFromLine(string lineText) + { + var args = new List(); + var currentArgBuilder = new StringBuilder(); + string currentArg = null; + bool isInQuotes = false; + for (int i = 0; i < lineText.Length; i++) + { + var c = lineText[i]; + if (c == ' ' && !isInQuotes) + { + currentArg = currentArgBuilder.ToString(); + if (!currentArg.IsNullOrWhiteSpace()) + { + args.Add(currentArg); + } + + currentArgBuilder = new StringBuilder(); + } + else + { + if (c == '\"') + { + isInQuotes = !isInQuotes; + } + else + { + currentArgBuilder.Append(c); + } + } + } + + currentArg = currentArgBuilder.ToString(); + if (!currentArg.IsNullOrWhiteSpace()) + { + args.Add(currentArg); + } + + return args.ToArray(); + } } } \ No newline at end of file diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Args/ICommandLineArgumentParser.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Args/ICommandLineArgumentParser.cs index c467541210..4e8ee7cd77 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Args/ICommandLineArgumentParser.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Args/ICommandLineArgumentParser.cs @@ -3,5 +3,7 @@ public interface ICommandLineArgumentParser { CommandLineArgs Parse(string[] args); + + CommandLineArgs Parse(string lineText); } } \ No newline at end of file diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Auth/AuthService.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Auth/AuthService.cs index 61008ee826..bb16733e16 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Auth/AuthService.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Auth/AuthService.cs @@ -9,8 +9,10 @@ using IdentityModel; using Microsoft.Extensions.Logging; using Volo.Abp.Cli.Commands; using Volo.Abp.Cli.Http; +using Volo.Abp.Cli.ProjectBuilding; using Volo.Abp.DependencyInjection; using Volo.Abp.IdentityModel; +using Volo.Abp.Json; using Volo.Abp.Threading; namespace Volo.Abp.Cli.Auth @@ -18,21 +20,54 @@ namespace Volo.Abp.Cli.Auth public class AuthService : ITransientDependency { protected IIdentityModelAuthenticationService AuthenticationService { get; } - protected ILogger Logger { get; } + protected ILogger Logger { get; } protected CliHttpClientFactory CliHttpClientFactory { get; } + public RemoteServiceExceptionHandler RemoteServiceExceptionHandler { get; } + public IJsonSerializer JsonSerializer { get; } public ICancellationTokenProvider CancellationTokenProvider { get; } public AuthService( IIdentityModelAuthenticationService authenticationService, - ILogger logger, + ILogger logger, ICancellationTokenProvider cancellationTokenProvider, - CliHttpClientFactory cliHttpClientFactory + CliHttpClientFactory cliHttpClientFactory, + RemoteServiceExceptionHandler remoteServiceExceptionHandler, + IJsonSerializer jsonSerializer ) { AuthenticationService = authenticationService; Logger = logger; CancellationTokenProvider = cancellationTokenProvider; CliHttpClientFactory = cliHttpClientFactory; + RemoteServiceExceptionHandler = remoteServiceExceptionHandler; + JsonSerializer = jsonSerializer; + } + + public async Task GetLoginInfoAsync() + { + if (!IsLoggedIn()) + { + return null; + } + + var url = $"{CliUrls.WwwAbpIo}api/license/login-info"; + + var client = CliHttpClientFactory.CreateClient(); + + using (var response = await client.GetHttpResponseMessageWithRetryAsync(url, CancellationTokenProvider.Token, Logger)) + { + if (!response.IsSuccessStatusCode) + { + Logger.LogError("Remote server returns '{response.StatusCode}'"); + return null; + } + + await RemoteServiceExceptionHandler.EnsureSuccessfulHttpResponseAsync(response); + + var responseContent = await response.Content.ReadAsStringAsync(); + + return JsonSerializer.Deserialize(responseContent); + } } public async Task LoginAsync(string userName, string password, string organizationName = null) @@ -108,4 +143,4 @@ namespace Volo.Abp.Cli.Auth return File.Exists(CliPaths.AccessToken); } } -} \ No newline at end of file +} diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Auth/LoginInfo.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Auth/LoginInfo.cs new file mode 100644 index 0000000000..2ad31421e5 --- /dev/null +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Auth/LoginInfo.cs @@ -0,0 +1,16 @@ + +namespace Volo.Abp.Cli.Auth +{ + public class LoginInfo + { + public string Name { get; set; } + + public string Surname { get; set; } + + public string Username { get; set; } + + public string EmailAddress { get; set; } + + public string Organization { get; set; } + } +} diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/CliService.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/CliService.cs index 11ba6dedde..cfae12c76e 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/CliService.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/CliService.cs @@ -3,9 +3,11 @@ using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging.Abstractions; using NuGet.Versioning; using System; +using System.Collections.Generic; using System.IO; using System.Linq; using System.Reflection; +using System.Text; using System.Threading.Tasks; using Volo.Abp.Cli.Args; using Volo.Abp.Cli.Commands; @@ -41,33 +43,76 @@ namespace Volo.Abp.Cli { Logger.LogInformation("ABP CLI (https://abp.io)"); - var commandLineArgs = CommandLineArgumentParser.Parse(args); - #if !DEBUG if (!commandLineArgs.Options.ContainsKey("skip-cli-version-check")) { await CheckCliVersionAsync(); } #endif - - var commandType = CommandSelector.Select(commandLineArgs); - - using (var scope = ServiceScopeFactory.CreateScope()) + var commandLineArgs = CommandLineArgumentParser.Parse(args); + + try { - var command = (IConsoleCommand)scope.ServiceProvider.GetRequiredService(commandType); - - try + if (commandLineArgs.IsCommand("batch")) + { + await RunBatchAsync(commandLineArgs); + } + else { - await command.ExecuteAsync(commandLineArgs); + await RunInternalAsync(commandLineArgs); } - catch (CliUsageException usageException) + } + catch (CliUsageException usageException) + { + Logger.LogWarning(usageException.Message); + } + catch (Exception ex) + { + Logger.LogException(ex); + } + } + + private async Task RunBatchAsync(CommandLineArgs commandLineArgs) + { + var targetFile = commandLineArgs.Target; + if (targetFile.IsNullOrWhiteSpace()) + { + throw new CliUsageException( + "Must provide a file name/path that contains a list of commands" + + Environment.NewLine + Environment.NewLine + + "Example: " + + " abp batch commands.txt" + ); + } + + var filePath = Path.Combine(Directory.GetCurrentDirectory(), targetFile); + var fileLines = File.ReadAllLines(filePath); + foreach (var line in fileLines) + { + var lineText = line; + if (lineText.IsNullOrWhiteSpace() || lineText.StartsWith("#")) { - Logger.LogWarning(usageException.Message); + continue; } - catch (Exception ex) + + if (lineText.Contains('#')) { - Logger.LogException(ex); + lineText = lineText.Substring(0, lineText.IndexOf('#')); } + + var args = CommandLineArgumentParser.Parse(lineText); + await RunInternalAsync(args); + } + } + + private async Task RunInternalAsync(CommandLineArgs commandLineArgs) + { + var commandType = CommandSelector.Select(commandLineArgs); + + using (var scope = ServiceScopeFactory.CreateScope()) + { + var command = (IConsoleCommand) scope.ServiceProvider.GetRequiredService(commandType); + await command.ExecuteAsync(commandLineArgs); } } diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/LoginInfoCommand..cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/LoginInfoCommand..cs new file mode 100644 index 0000000000..e5bd62c393 --- /dev/null +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/LoginInfoCommand..cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging.Abstractions; +using System.Text; +using System.Threading.Tasks; +using Volo.Abp.Cli.Args; +using Volo.Abp.Cli.Auth; +using Volo.Abp.DependencyInjection; + +namespace Volo.Abp.Cli.Commands +{ + public class LoginInfoCommand : IConsoleCommand, ITransientDependency + { + public ILogger Logger { get; set; } + + protected AuthService AuthService { get; } + + public LoginInfoCommand(AuthService authService) + { + AuthService = authService; + Logger = NullLogger.Instance; + } + + public async Task ExecuteAsync(CommandLineArgs commandLineArgs) + { + var loginInfo = await AuthService.GetLoginInfoAsync(); + + if (loginInfo == null) + { + Logger.LogError("Unable to get login info."); + return; + } + + var sb = new StringBuilder(); + sb.AppendLine(""); + sb.AppendLine($"Login info:"); + sb.AppendLine($"Name: {loginInfo.Name}"); + sb.AppendLine($"Surname: {loginInfo.Surname}"); + sb.AppendLine($"Username: {loginInfo.Username}"); + sb.AppendLine($"Email Address: {loginInfo.EmailAddress}"); + sb.AppendLine($"Organization: {loginInfo.Organization}"); + Logger.LogInformation(sb.ToString()); + } + + public string GetUsageInfo() + { + var sb = new StringBuilder(); + + sb.AppendLine(""); + sb.AppendLine("Usage:"); + sb.AppendLine(" abp login-info"); + sb.AppendLine(""); + sb.AppendLine("See the documentation for more info: https://docs.abp.io/en/abp/latest/CLI"); + + return sb.ToString(); + } + + public string GetShortDescription() + { + return "Show your login info."; + } + } +} diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/NewCommand.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/NewCommand.cs index 83cce36fce..c8757e1252 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/NewCommand.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/NewCommand.cs @@ -61,6 +61,11 @@ namespace Volo.Abp.Cli.Commands ); } + if (!ProjectNameValidator.IsValid(projectName)) + { + throw new CliUsageException("The project name is invalid! Please specify a different name."); + } + Logger.LogInformation("Creating your project..."); Logger.LogInformation("Project name: " + projectName); @@ -554,4 +559,4 @@ namespace Volo.Abp.Cli.Commands } } } -} +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/Services/ConnectionStringProvider.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/Services/ConnectionStringProvider.cs index 2e53f6a84c..e4c5394a60 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/Services/ConnectionStringProvider.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/Services/ConnectionStringProvider.cs @@ -16,12 +16,12 @@ namespace Volo.Abp.Cli.Commands.Services case DatabaseManagementSystem.MySQL: return "Server=localhost;Port=3306;Database=MyProjectName;Uid=root;Pwd=myPassword;"; case DatabaseManagementSystem.PostgreSQL: - return "Host=localhost;Port=5432;Database=MyProjectName;User ID=root;Password=myPassword;Pooling=true;MinimumPoolSize=0;MaximumPoolSize=100;Connection Lifetime=0;"; + return "Host=localhost;Port=5432;Database=MyProjectName;User ID=root;Password=myPassword;"; case DatabaseManagementSystem.Oracle: case DatabaseManagementSystem.OracleDevart: return "Data Source=MyProjectName;Integrated Security=yes;"; case DatabaseManagementSystem.SQLite: - return $"Data Source={Path.Combine(outputFolder , "MyProjectName.db")};".Replace("\\", "\\\\"); + return $"Data Source={Path.Combine(outputFolder, "MyProjectName.db")};".Replace("\\", "\\\\"); default: return null; } diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/SolutionModuleAdder.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/SolutionModuleAdder.cs index 2d59392dcd..9a30fd7fd3 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/SolutionModuleAdder.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/SolutionModuleAdder.cs @@ -301,13 +301,21 @@ namespace Volo.Abp.Cli.ProjectModification private async Task RemoveProjectFromSolutionAsync(string moduleSolutionFile, string projectName) { - await SolutionFileModifier.RemoveProjectFromSolutionFileAsync(moduleSolutionFile, projectName); + await SolutionFileModifier.RemoveProjectFromSolutionFileAsync(moduleSolutionFile, projectName); - var projectFolderPath = Path.Combine(Path.GetDirectoryName(moduleSolutionFile), "src", projectName); + var projectFolderPath = Path.Combine(Path.GetDirectoryName(moduleSolutionFile), "src", projectName); + if (Directory.Exists(projectFolderPath)) + { + Directory.Delete(projectFolderPath, true); + } + else + { + projectFolderPath = Path.Combine(Path.GetDirectoryName(moduleSolutionFile), "test", projectName); if (Directory.Exists(projectFolderPath)) { Directory.Delete(projectFolderPath, true); } + } } private void ChangeDomainTestReferenceToMongoDB(ModuleWithMastersInfo module, string moduleSolutionFile) diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Utils/ProjectNameValidator.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Utils/ProjectNameValidator.cs new file mode 100644 index 0000000000..8430cd79a0 --- /dev/null +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Utils/ProjectNameValidator.cs @@ -0,0 +1,68 @@ +using System; +using System.Collections.Generic; +using System.Linq; + +namespace Volo.Abp.Cli.Utils +{ + public static class ProjectNameValidator + { + private static readonly string[] IllegalProjectNames = new[] + { + "MyCompanyName.MyProjectName", + "MyProjectName", + "CON", //Windows doesn't accept these names as file name + "AUX", + "PRN", + "COM1", + "LPT2" + }; + + private static bool HasParentDirectoryString(string projectName) + { + return projectName.Contains(".."); + } + + private static bool HasSurrogateOrControlChar(string projectName) + { + return projectName.Any(chr => char.IsControl(chr) || char.IsSurrogate(chr)); + } + + private static bool IsIllegalProjectName(string projectName) + { + foreach (var illegalProjectName in IllegalProjectNames) + { + if (projectName.Equals(illegalProjectName, StringComparison.OrdinalIgnoreCase)) + { + return true; + } + } + + return false; + } + + public static bool IsValid(string projectName) + { + if (projectName == null) + { + throw new CliUsageException("Project name cannot be empty!"); + } + + if (HasSurrogateOrControlChar(projectName)) + { + return false; + } + + if (HasParentDirectoryString(projectName)) + { + return false; + } + + if (IsIllegalProjectName(projectName)) + { + return false; + } + + return true; + } + } +} diff --git a/framework/src/Volo.Abp.Core/Microsoft/Extensions/DependencyInjection/ServiceCollectionRegistrationActionExtensions.cs b/framework/src/Volo.Abp.Core/Microsoft/Extensions/DependencyInjection/ServiceCollectionRegistrationActionExtensions.cs index 59cbdec860..41676f00d5 100644 --- a/framework/src/Volo.Abp.Core/Microsoft/Extensions/DependencyInjection/ServiceCollectionRegistrationActionExtensions.cs +++ b/framework/src/Volo.Abp.Core/Microsoft/Extensions/DependencyInjection/ServiceCollectionRegistrationActionExtensions.cs @@ -28,6 +28,16 @@ namespace Microsoft.Extensions.DependencyInjection return actionList; } + + public static void DisableAbpClassInterceptors(this IServiceCollection services) + { + GetOrCreateRegistrationActionList(services).IsClassInterceptorsDisabled = true; + } + + public static bool IsAbpClassInterceptorsDisabled(this IServiceCollection services) + { + return GetOrCreateRegistrationActionList(services).IsClassInterceptorsDisabled; + } // OnExposing diff --git a/framework/src/Volo.Abp.Core/Volo/Abp/DependencyInjection/ServiceRegistrationActionList.cs b/framework/src/Volo.Abp.Core/Volo/Abp/DependencyInjection/ServiceRegistrationActionList.cs index bb72d28929..19ab6cdba2 100644 --- a/framework/src/Volo.Abp.Core/Volo/Abp/DependencyInjection/ServiceRegistrationActionList.cs +++ b/framework/src/Volo.Abp.Core/Volo/Abp/DependencyInjection/ServiceRegistrationActionList.cs @@ -5,6 +5,6 @@ namespace Volo.Abp.DependencyInjection { public class ServiceRegistrationActionList : List> { - + public bool IsClassInterceptorsDisabled { get; set; } } } \ No newline at end of file diff --git a/framework/src/Volo.Abp.Core/Volo/Abp/Internal/InternalServiceCollectionExtensions.cs b/framework/src/Volo.Abp.Core/Volo/Abp/Internal/InternalServiceCollectionExtensions.cs index ee06003204..5c729b4197 100644 --- a/framework/src/Volo.Abp.Core/Volo/Abp/Internal/InternalServiceCollectionExtensions.cs +++ b/framework/src/Volo.Abp.Core/Volo/Abp/Internal/InternalServiceCollectionExtensions.cs @@ -4,6 +4,7 @@ using Microsoft.Extensions.DependencyInjection.Extensions; using Volo.Abp.Logging; using Volo.Abp.Modularity; using Volo.Abp.Reflection; +using Volo.Abp.SimpleStateChecking; namespace Volo.Abp.Internal { @@ -40,6 +41,8 @@ namespace Volo.Abp.Internal services.AddAssemblyOf(); + services.AddTransient(typeof(ISimpleStateCheckerManager<>), typeof(SimpleStateCheckerManager<>)); + services.Configure(options => { options.Contributors.Add(); diff --git a/framework/src/Volo.Abp.Core/Volo/Abp/SimpleStateChecking/AbpSimpleStateCheckerOptions.cs b/framework/src/Volo.Abp.Core/Volo/Abp/SimpleStateChecking/AbpSimpleStateCheckerOptions.cs new file mode 100644 index 0000000000..66201449a1 --- /dev/null +++ b/framework/src/Volo.Abp.Core/Volo/Abp/SimpleStateChecking/AbpSimpleStateCheckerOptions.cs @@ -0,0 +1,15 @@ +using Volo.Abp.Collections; + +namespace Volo.Abp.SimpleStateChecking +{ + public class AbpSimpleStateCheckerOptions + where TState : IHasSimpleStateCheckers + { + public ITypeList> GlobalStateCheckers { get; } + + public AbpSimpleStateCheckerOptions() + { + GlobalStateCheckers = new TypeList>(); + } + } +} diff --git a/framework/src/Volo.Abp.Core/Volo/Abp/SimpleStateChecking/IHasSimpleStateCheckers.cs b/framework/src/Volo.Abp.Core/Volo/Abp/SimpleStateChecking/IHasSimpleStateCheckers.cs new file mode 100644 index 0000000000..b9548e3bf4 --- /dev/null +++ b/framework/src/Volo.Abp.Core/Volo/Abp/SimpleStateChecking/IHasSimpleStateCheckers.cs @@ -0,0 +1,10 @@ +using System.Collections.Generic; + +namespace Volo.Abp.SimpleStateChecking +{ + public interface IHasSimpleStateCheckers + where TState : IHasSimpleStateCheckers + { + List> StateCheckers { get; } + } +} diff --git a/framework/src/Volo.Abp.Core/Volo/Abp/SimpleStateChecking/ISimpleBatchStateChecker.cs b/framework/src/Volo.Abp.Core/Volo/Abp/SimpleStateChecking/ISimpleBatchStateChecker.cs new file mode 100644 index 0000000000..ff364ff223 --- /dev/null +++ b/framework/src/Volo.Abp.Core/Volo/Abp/SimpleStateChecking/ISimpleBatchStateChecker.cs @@ -0,0 +1,10 @@ +using System.Threading.Tasks; + +namespace Volo.Abp.SimpleStateChecking +{ + public interface ISimpleBatchStateChecker : ISimpleStateChecker + where TState : IHasSimpleStateCheckers + { + Task> IsEnabledAsync(SimpleBatchStateCheckerContext context); + } +} diff --git a/framework/src/Volo.Abp.Core/Volo/Abp/SimpleStateChecking/ISimpleStateChecker.cs b/framework/src/Volo.Abp.Core/Volo/Abp/SimpleStateChecking/ISimpleStateChecker.cs new file mode 100644 index 0000000000..6d50044520 --- /dev/null +++ b/framework/src/Volo.Abp.Core/Volo/Abp/SimpleStateChecking/ISimpleStateChecker.cs @@ -0,0 +1,10 @@ +using System.Threading.Tasks; + +namespace Volo.Abp.SimpleStateChecking +{ + public interface ISimpleStateChecker + where TState : IHasSimpleStateCheckers + { + Task IsEnabledAsync(SimpleStateCheckerContext context); + } +} diff --git a/framework/src/Volo.Abp.Core/Volo/Abp/SimpleStateChecking/ISimpleStateCheckerManager.cs b/framework/src/Volo.Abp.Core/Volo/Abp/SimpleStateChecking/ISimpleStateCheckerManager.cs new file mode 100644 index 0000000000..4ea98f7e68 --- /dev/null +++ b/framework/src/Volo.Abp.Core/Volo/Abp/SimpleStateChecking/ISimpleStateCheckerManager.cs @@ -0,0 +1,12 @@ +using System.Threading.Tasks; + +namespace Volo.Abp.SimpleStateChecking +{ + public interface ISimpleStateCheckerManager + where TState : IHasSimpleStateCheckers + { + Task IsEnabledAsync(TState state); + + Task> IsEnabledAsync(TState[] states); + } +} diff --git a/framework/src/Volo.Abp.Core/Volo/Abp/SimpleStateChecking/SimpleBatchStateCheckerBase.cs b/framework/src/Volo.Abp.Core/Volo/Abp/SimpleStateChecking/SimpleBatchStateCheckerBase.cs new file mode 100644 index 0000000000..43b2e2a6fe --- /dev/null +++ b/framework/src/Volo.Abp.Core/Volo/Abp/SimpleStateChecking/SimpleBatchStateCheckerBase.cs @@ -0,0 +1,16 @@ +using System.Linq; +using System.Threading.Tasks; + +namespace Volo.Abp.SimpleStateChecking +{ + public abstract class SimpleBatchStateCheckerBase: ISimpleBatchStateChecker + where TState : IHasSimpleStateCheckers + { + public async Task IsEnabledAsync(SimpleStateCheckerContext context) + { + return (await IsEnabledAsync(new SimpleBatchStateCheckerContext(context.ServiceProvider, new[] {context.State}))).Values.All(x => x); + } + + public abstract Task> IsEnabledAsync(SimpleBatchStateCheckerContext context); + } +} diff --git a/framework/src/Volo.Abp.Core/Volo/Abp/SimpleStateChecking/SimpleBatchStateCheckerContext.cs b/framework/src/Volo.Abp.Core/Volo/Abp/SimpleStateChecking/SimpleBatchStateCheckerContext.cs new file mode 100644 index 0000000000..ae5826a3e1 --- /dev/null +++ b/framework/src/Volo.Abp.Core/Volo/Abp/SimpleStateChecking/SimpleBatchStateCheckerContext.cs @@ -0,0 +1,18 @@ +using System; + +namespace Volo.Abp.SimpleStateChecking +{ + public class SimpleBatchStateCheckerContext + where TState : IHasSimpleStateCheckers + { + public IServiceProvider ServiceProvider { get; } + + public TState[] States { get; } + + public SimpleBatchStateCheckerContext(IServiceProvider serviceProvider, TState[] states) + { + ServiceProvider = serviceProvider; + States = states; + } + } +} diff --git a/framework/src/Volo.Abp.Core/Volo/Abp/SimpleStateChecking/SimpleStateCheckerContext.cs b/framework/src/Volo.Abp.Core/Volo/Abp/SimpleStateChecking/SimpleStateCheckerContext.cs new file mode 100644 index 0000000000..04e9da4720 --- /dev/null +++ b/framework/src/Volo.Abp.Core/Volo/Abp/SimpleStateChecking/SimpleStateCheckerContext.cs @@ -0,0 +1,18 @@ +using System; + +namespace Volo.Abp.SimpleStateChecking +{ + public class SimpleStateCheckerContext + where TState : IHasSimpleStateCheckers + { + public IServiceProvider ServiceProvider { get; } + + public TState State { get; } + + public SimpleStateCheckerContext(IServiceProvider serviceProvider, TState state) + { + ServiceProvider = serviceProvider; + State = state; + } + } +} diff --git a/framework/src/Volo.Abp.Core/Volo/Abp/SimpleStateChecking/SimpleStateCheckerManager.cs b/framework/src/Volo.Abp.Core/Volo/Abp/SimpleStateChecking/SimpleStateCheckerManager.cs new file mode 100644 index 0000000000..61a252850d --- /dev/null +++ b/framework/src/Volo.Abp.Core/Volo/Abp/SimpleStateChecking/SimpleStateCheckerManager.cs @@ -0,0 +1,112 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Options; +using Volo.Abp.DependencyInjection; + +namespace Volo.Abp.SimpleStateChecking +{ + public class SimpleStateCheckerManager : ISimpleStateCheckerManager + where TState : IHasSimpleStateCheckers + { + protected IServiceProvider ServiceProvider { get; } + + protected AbpSimpleStateCheckerOptions Options { get; } + + public SimpleStateCheckerManager(IServiceProvider serviceProvider, IOptions> options) + { + ServiceProvider = serviceProvider; + Options = options.Value; + } + + public virtual async Task IsEnabledAsync(TState state) + { + return await InternalIsEnabledAsync(state, true); + } + + public virtual async Task> IsEnabledAsync(TState[] states) + { + var result = new SimpleStateCheckerResult(states); + + using (var scope = ServiceProvider.CreateScope()) + { + var batchStateCheckers = states.SelectMany(x => x.StateCheckers) + .Where(x => x is ISimpleBatchStateChecker) + .Cast>() + .GroupBy(x => x) + .Select(x => x.Key); + + foreach (var stateChecker in batchStateCheckers) + { + var context = new SimpleBatchStateCheckerContext( + scope.ServiceProvider.GetRequiredService(), + states.Where(x => x.StateCheckers.Contains(stateChecker)).ToArray()); + + foreach (var x in await stateChecker.IsEnabledAsync(context)) + { + result[x.Key] = x.Value; + } + + if (result.Values.All(x => !x)) + { + return result; + } + } + + foreach (ISimpleBatchStateChecker globalStateChecker in Options.GlobalStateCheckers + .Where(x => typeof(ISimpleBatchStateChecker).IsAssignableFrom(x)) + .Select(x => ServiceProvider.GetRequiredService(x))) + { + var context = new SimpleBatchStateCheckerContext( + scope.ServiceProvider.GetRequiredService(), + states.Where(x => result.Any(y => y.Key.Equals(x) && y.Value)).ToArray()); + + foreach (var x in await globalStateChecker.IsEnabledAsync(context)) + { + result[x.Key] = x.Value; + } + } + + foreach (var state in states) + { + if (result[state]) + { + result[state] = await InternalIsEnabledAsync(state, false); + } + } + + return result; + } + } + + protected virtual async Task InternalIsEnabledAsync(TState state, bool useBatchChecker) + { + using (var scope = ServiceProvider.CreateScope()) + { + var context = new SimpleStateCheckerContext(scope.ServiceProvider.GetRequiredService(), state); + + foreach (var provider in state.StateCheckers.WhereIf(!useBatchChecker, x => x is not ISimpleBatchStateChecker)) + { + if (!await provider.IsEnabledAsync(context)) + { + return false; + } + } + + foreach (ISimpleStateChecker provider in Options.GlobalStateCheckers + .WhereIf(!useBatchChecker, x => !typeof(ISimpleBatchStateChecker).IsAssignableFrom(x)) + .Select(x => ServiceProvider.GetRequiredService(x))) + { + if (!await provider.IsEnabledAsync(context)) + { + return false; + } + } + + return true; + } + } + } +} diff --git a/framework/src/Volo.Abp.Core/Volo/Abp/SimpleStateChecking/SimpleStateCheckerResult.cs b/framework/src/Volo.Abp.Core/Volo/Abp/SimpleStateChecking/SimpleStateCheckerResult.cs new file mode 100644 index 0000000000..a3c1dc8020 --- /dev/null +++ b/framework/src/Volo.Abp.Core/Volo/Abp/SimpleStateChecking/SimpleStateCheckerResult.cs @@ -0,0 +1,21 @@ +using System.Collections.Generic; + +namespace Volo.Abp.SimpleStateChecking +{ + public class SimpleStateCheckerResult : Dictionary + where TState : IHasSimpleStateCheckers + { + public SimpleStateCheckerResult() + { + + } + + public SimpleStateCheckerResult(IEnumerable states, bool initValue = true) + { + foreach (var state in states) + { + Add(state, initValue); + } + } + } +} diff --git a/framework/src/Volo.Abp.Data/Volo/Abp/Data/IConnectionStringResolverExtensions.cs b/framework/src/Volo.Abp.Data/Volo/Abp/Data/IConnectionStringResolverExtensions.cs index 1fa097964c..ceeaec8f8f 100644 --- a/framework/src/Volo.Abp.Data/Volo/Abp/Data/IConnectionStringResolverExtensions.cs +++ b/framework/src/Volo.Abp.Data/Volo/Abp/Data/IConnectionStringResolverExtensions.cs @@ -10,13 +10,26 @@ namespace Volo.Abp.Data [Obsolete("Use ResolveAsync method")] public static string Resolve(this IConnectionStringResolver resolver) { - return resolver.Resolve(ConnectionStringNameAttribute.GetConnStringName()); + return resolver.Resolve(typeof(T)); } [NotNull] public static Task ResolveAsync(this IConnectionStringResolver resolver) { - return resolver.ResolveAsync(ConnectionStringNameAttribute.GetConnStringName()); + return resolver.ResolveAsync(typeof(T)); + } + + [NotNull] + [Obsolete("Use ResolveAsync method")] + public static string Resolve(this IConnectionStringResolver resolver, Type type) + { + return resolver.Resolve(ConnectionStringNameAttribute.GetConnStringName(type)); + } + + [NotNull] + public static Task ResolveAsync(this IConnectionStringResolver resolver, Type type) + { + return resolver.ResolveAsync(ConnectionStringNameAttribute.GetConnStringName(type)); } } } diff --git a/framework/src/Volo.Abp.Ddd.Application.Contracts/Volo/Abp/Application/Localization/Resources/AbpDdd/hi.json b/framework/src/Volo.Abp.Ddd.Application.Contracts/Volo/Abp/Application/Localization/Resources/AbpDdd/hi.json new file mode 100644 index 0000000000..d5189da8e5 --- /dev/null +++ b/framework/src/Volo.Abp.Ddd.Application.Contracts/Volo/Abp/Application/Localization/Resources/AbpDdd/hi.json @@ -0,0 +1,6 @@ +{ + "culture": "hi", + "texts": { + "MaxResultCountExceededExceptionMessage": "{0} {1} से अधिक नहीं हो सकता! अधिक परिणाम की अनुमति देने के लिए सर्वर पक्ष पर {2}। {3} बढ़ाएँ।" + } +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.Ddd.Application.Contracts/Volo/Abp/Application/Localization/Resources/AbpDdd/it.json b/framework/src/Volo.Abp.Ddd.Application.Contracts/Volo/Abp/Application/Localization/Resources/AbpDdd/it.json new file mode 100644 index 0000000000..1661d0624f --- /dev/null +++ b/framework/src/Volo.Abp.Ddd.Application.Contracts/Volo/Abp/Application/Localization/Resources/AbpDdd/it.json @@ -0,0 +1,6 @@ +{ + "culture": "it", + "texts": { + "MaxResultCountExceededExceptionMessage": "{0} non può essere maggiore di {1}! Aumenta {2}. {3} sul lato server per consentire più risultati." + } +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.Ddd.Application/Volo/Abp/Application/Services/ApplicationService.cs b/framework/src/Volo.Abp.Ddd.Application/Volo/Abp/Application/Services/ApplicationService.cs index 922b887bfa..821bff2ef3 100644 --- a/framework/src/Volo.Abp.Ddd.Application/Volo/Abp/Application/Services/ApplicationService.cs +++ b/framework/src/Volo.Abp.Ddd.Application/Volo/Abp/Application/Services/ApplicationService.cs @@ -10,6 +10,7 @@ using System.Threading.Tasks; using Volo.Abp.Aspects; using Volo.Abp.Auditing; using Volo.Abp.Authorization; +using Volo.Abp.Data; using Volo.Abp.DependencyInjection; using Volo.Abp.Features; using Volo.Abp.GlobalFeatures; @@ -59,6 +60,8 @@ namespace Volo.Abp.Application.Services protected ILoggerFactory LoggerFactory => LazyServiceProvider.LazyGetRequiredService(); protected ICurrentTenant CurrentTenant => LazyServiceProvider.LazyGetRequiredService(); + + protected IDataFilter DataFilter => LazyServiceProvider.LazyGetRequiredService(); protected ICurrentUser CurrentUser => LazyServiceProvider.LazyGetRequiredService(); diff --git a/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/DependencyInjection/AbpCommonDbContextRegistrationOptions.cs b/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/DependencyInjection/AbpCommonDbContextRegistrationOptions.cs index 6408e3f0fa..ee172b3409 100644 --- a/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/DependencyInjection/AbpCommonDbContextRegistrationOptions.cs +++ b/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/DependencyInjection/AbpCommonDbContextRegistrationOptions.cs @@ -55,7 +55,7 @@ namespace Volo.Abp.DependencyInjection throw new AbpException($"{OriginalDbContextType.AssemblyQualifiedName} should inherit/implement {otherDbContextType.AssemblyQualifiedName}!"); } - ReplacedDbContextTypes.Add(otherDbContextType); + ReplacedDbContextTypes.AddIfNotContains(otherDbContextType); return this; } @@ -93,9 +93,9 @@ namespace Volo.Abp.DependencyInjection public IAbpCommonDbContextRegistrationOptionsBuilder AddDefaultRepository(Type entityType) { EntityHelper.CheckEntity(entityType); - + SpecifiedDefaultRepositories.AddIfNotContains(entityType); - + return this; } diff --git a/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/DependencyInjection/ReplaceDbContextAttribute.cs b/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/DependencyInjection/ReplaceDbContextAttribute.cs new file mode 100644 index 0000000000..625e6841a0 --- /dev/null +++ b/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/DependencyInjection/ReplaceDbContextAttribute.cs @@ -0,0 +1,15 @@ +using System; + +namespace Volo.Abp.DependencyInjection +{ + [AttributeUsage(AttributeTargets.Class, AllowMultiple = true)] + public class ReplaceDbContextAttribute : Attribute + { + public Type[] ReplacedDbContextTypes { get; } + + public ReplaceDbContextAttribute(params Type[] replacedDbContextTypes) + { + ReplacedDbContextTypes = replacedDbContextTypes; + } + } +} diff --git a/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Localization/hi.json b/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Localization/hi.json new file mode 100644 index 0000000000..4b69d8588d --- /dev/null +++ b/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Localization/hi.json @@ -0,0 +1,25 @@ +{ + "culture": "hi", + "texts": { + "DisplayName:Abp.Mailing.DefaultFromAddress": "पते से डिफ़ॉल्ट", + "DisplayName:Abp.Mailing.DefaultFromDisplayName": "प्रदर्शन नाम से डिफ़ॉल्ट", + "DisplayName:Abp.Mailing.Smtp.Host": "मेज़बान", + "DisplayName:Abp.Mailing.Smtp.Port": "बंदरगाह", + "DisplayName:Abp.Mailing.Smtp.UserName": "उपयोगकर्ता नाम", + "DisplayName:Abp.Mailing.Smtp.Password": "कुंजिका", + "DisplayName:Abp.Mailing.Smtp.Domain": "डोमेन", + "DisplayName:Abp.Mailing.Smtp.EnableSsl": "SSL सक्षम करें", + "DisplayName:Abp.Mailing.Smtp.UseDefaultCredentials": "डिफ़ॉल्ट क्रेडेंशियल्स का उपयोग करें", + "Description:Abp.Mailing.DefaultFromAddress": "पते से डिफ़ॉल्ट", + "Description:Abp.Mailing.DefaultFromDisplayName": "प्रदर्शन नाम से डिफ़ॉल्ट", + "Description:Abp.Mailing.Smtp.Host": "SMTP लेनदेन के लिए उपयोग किए गए होस्ट का नाम या IP पता।", + "Description:Abp.Mailing.Smtp.Port": "SMTP लेनदेन के लिए उपयोग किया जाने वाला पोर्ट।", + "Description:Abp.Mailing.Smtp.UserName": "उपयोगकर्ता नाम क्रेडेंशियल्स के साथ जुड़ा हुआ है।", + "Description:Abp.Mailing.Smtp.Password": "क्रेडेंशियल्स के साथ जुड़े उपयोगकर्ता नाम का पासवर्ड।", + "Description:Abp.Mailing.Smtp.Domain": "डोमेन या कंप्यूटर का नाम जो क्रेडेंशियल्स को सत्यापित करता है।", + "Description:Abp.Mailing.Smtp.EnableSsl": "क्या SmtpClient कनेक्शन को एन्क्रिप्ट करने के लिए सिक्योर सॉकेट्स लेयर (एसएसएल) का उपयोग करता है।", + "Description:Abp.Mailing.Smtp.UseDefaultCredentials": "क्या DefaultCredentials अनुरोधों के साथ भेजे जाते हैं।", + "TextTemplate:StandardEmailTemplates.Layout": "डिफ़ॉल्ट ईमेल लेआउट टेम्पलेट", + "TextTemplate:StandardEmailTemplates.Message": "ईमेल के लिए सरल संदेश टेम्पलेट" + } +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Localization/it.json b/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Localization/it.json new file mode 100644 index 0000000000..34b5f573c5 --- /dev/null +++ b/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Localization/it.json @@ -0,0 +1,25 @@ +{ + "culture": "it", + "texts": { + "DisplayName:Abp.Mailing.DefaultFromAddress": "Indirizzo predefinito dall'indirizzo", + "DisplayName:Abp.Mailing.DefaultFromDisplayName": "Predefinito dal nome visualizzato", + "DisplayName:Abp.Mailing.Smtp.Host": "Ospite", + "DisplayName:Abp.Mailing.Smtp.Port": "Porta", + "DisplayName:Abp.Mailing.Smtp.UserName": "Nome utente", + "DisplayName:Abp.Mailing.Smtp.Password": "Parola d'ordine", + "DisplayName:Abp.Mailing.Smtp.Domain": "Dominio", + "DisplayName:Abp.Mailing.Smtp.EnableSsl": "Abilita SSL", + "DisplayName:Abp.Mailing.Smtp.UseDefaultCredentials": "Usa credenziali predefinite", + "Description:Abp.Mailing.DefaultFromAddress": "L'indirizzo predefinito da", + "Description:Abp.Mailing.DefaultFromDisplayName": "Il valore predefinito dal nome visualizzato", + "Description:Abp.Mailing.Smtp.Host": "Il nome o l'indirizzo IP dell'host utilizzato per le transazioni SMTP.", + "Description:Abp.Mailing.Smtp.Port": "La porta utilizzata per le transazioni SMTP.", + "Description:Abp.Mailing.Smtp.UserName": "Nome utente associato alle credenziali.", + "Description:Abp.Mailing.Smtp.Password": "La password per il nome utente associato alle credenziali.", + "Description:Abp.Mailing.Smtp.Domain": "Il nome di dominio o computer che verifica le credenziali.", + "Description:Abp.Mailing.Smtp.EnableSsl": "Se SmtpClient utilizza SSL (Secure Sockets Layer) per crittografare la connessione.", + "Description:Abp.Mailing.Smtp.UseDefaultCredentials": "Indica se DefaultCredentials vengono inviati con richieste.", + "TextTemplate:StandardEmailTemplates.Layout": "Modello di layout di posta elettronica predefinito", + "TextTemplate:StandardEmailTemplates.Message": "Modello di messaggio semplice per e-mail" + } +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.EntityFrameworkCore/Microsoft/Extensions/DependencyInjection/AbpEfCoreServiceCollectionExtensions.cs b/framework/src/Volo.Abp.EntityFrameworkCore/Microsoft/Extensions/DependencyInjection/AbpEfCoreServiceCollectionExtensions.cs index 538614ee22..a48575ddcc 100644 --- a/framework/src/Volo.Abp.EntityFrameworkCore/Microsoft/Extensions/DependencyInjection/AbpEfCoreServiceCollectionExtensions.cs +++ b/framework/src/Volo.Abp.EntityFrameworkCore/Microsoft/Extensions/DependencyInjection/AbpEfCoreServiceCollectionExtensions.cs @@ -1,5 +1,8 @@ using System; +using System.Linq; +using System.Reflection; using Microsoft.Extensions.DependencyInjection.Extensions; +using Volo.Abp.DependencyInjection; using Volo.Abp.EntityFrameworkCore; using Volo.Abp.EntityFrameworkCore.DependencyInjection; @@ -8,13 +11,22 @@ namespace Microsoft.Extensions.DependencyInjection public static class AbpEfCoreServiceCollectionExtensions { public static IServiceCollection AddAbpDbContext( - this IServiceCollection services, + this IServiceCollection services, Action optionsBuilder = null) where TDbContext : AbpDbContext { services.AddMemoryCache(); var options = new AbpDbContextRegistrationOptions(typeof(TDbContext), services); + + var replacedDbContextTypes = typeof(TDbContext).GetCustomAttributes(true) + .SelectMany( x => x.ReplacedDbContextTypes).ToList(); + + foreach (var dbContextType in replacedDbContextTypes) + { + options.ReplaceDbContext(dbContextType); + } + optionsBuilder?.Invoke(options); services.TryAddTransient(DbContextOptionsFactory.Create); diff --git a/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/AbpDbContextOptions.cs b/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/AbpDbContextOptions.cs index 92c6935900..75dd6a5dc4 100644 --- a/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/AbpDbContextOptions.cs +++ b/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/AbpDbContextOptions.cs @@ -39,6 +39,11 @@ namespace Volo.Abp.EntityFrameworkCore DefaultConfigureAction = action; } + public bool IsConfiguredDefault() + { + return DefaultConfigureAction != null; + } + public void PreConfigure([NotNull] Action> action) where TDbContext : AbpDbContext { @@ -60,6 +65,16 @@ namespace Volo.Abp.EntityFrameworkCore ConfigureActions[typeof(TDbContext)] = action; } + + public bool IsConfigured() + { + return IsConfigured(typeof(TDbContext)); + } + + public bool IsConfigured(Type dbContextType) + { + return ConfigureActions.ContainsKey(dbContextType); + } internal Type GetReplacedTypeOrSelf(Type dbContextType) { diff --git a/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/AbpEntityFrameworkCoreModule.cs b/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/AbpEntityFrameworkCoreModule.cs index e92c8d35fa..b5d9eb8436 100644 --- a/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/AbpEntityFrameworkCoreModule.cs +++ b/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/AbpEntityFrameworkCoreModule.cs @@ -1,6 +1,8 @@ using Microsoft.EntityFrameworkCore.Diagnostics; +using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection.Extensions; using Volo.Abp.Domain; +using Volo.Abp.EntityFrameworkCore.DependencyInjection; using Volo.Abp.Modularity; using Volo.Abp.Uow.EntityFrameworkCore; diff --git a/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/Uow/EntityFrameworkCore/UnitOfWorkDbContextProvider.cs b/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/Uow/EntityFrameworkCore/UnitOfWorkDbContextProvider.cs index 2fa56b550b..e5e4c2584a 100644 --- a/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/Uow/EntityFrameworkCore/UnitOfWorkDbContextProvider.cs +++ b/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/Uow/EntityFrameworkCore/UnitOfWorkDbContextProvider.cs @@ -62,10 +62,9 @@ namespace Volo.Abp.Uow.EntityFrameworkCore throw new AbpException("A DbContext can only be created inside a unit of work!"); } - var connectionStringName = ConnectionStringNameAttribute.GetConnStringName(); - var connectionString = ResolveConnectionString(connectionStringName); - var targetDbContextType = _options.GetReplacedTypeOrSelf(typeof(TDbContext)); + var connectionStringName = ConnectionStringNameAttribute.GetConnStringName(targetDbContextType); + var connectionString = ResolveConnectionString(connectionStringName); var dbContextKey = $"{targetDbContextType.FullName}_{connectionString}"; var databaseApi = unitOfWork.GetOrAddDatabaseApi( @@ -85,10 +84,10 @@ namespace Volo.Abp.Uow.EntityFrameworkCore throw new AbpException("A DbContext can only be created inside a unit of work!"); } - var connectionStringName = ConnectionStringNameAttribute.GetConnStringName(); + var targetDbContextType = _options.GetReplacedTypeOrSelf(typeof(TDbContext)); + var connectionStringName = ConnectionStringNameAttribute.GetConnStringName(targetDbContextType); var connectionString = await ResolveConnectionStringAsync(connectionStringName); - var targetDbContextType = _options.GetReplacedTypeOrSelf(typeof(TDbContext)); var dbContextKey = $"{targetDbContextType.FullName}_{connectionString}"; var databaseApi = unitOfWork.FindDatabaseApi(dbContextKey); diff --git a/framework/src/Volo.Abp.ExceptionHandling/Volo/Abp/ExceptionHandling/Localization/hi.json b/framework/src/Volo.Abp.ExceptionHandling/Volo/Abp/ExceptionHandling/Localization/hi.json new file mode 100644 index 0000000000..47c8cdda55 --- /dev/null +++ b/framework/src/Volo.Abp.ExceptionHandling/Volo/Abp/ExceptionHandling/Localization/hi.json @@ -0,0 +1,25 @@ +{ + "culture": "hi", + "texts": { + "InternalServerErrorMessage": "आपके अनुरोध के दौरान एक आंतरिक त्रुटि हुई!", + "ValidationErrorMessage": "आपका अनुरोध मान्य नहीं है!", + "ValidationNarrativeErrorMessageTitle": "सत्यापन के दौरान निम्नलिखित त्रुटियों का पता चला था।", + "DefaultErrorMessage": "एक गलती हुई है!", + "DefaultErrorMessageDetail": "सर्वर द्वारा त्रुटि विवरण नहीं भेजा गया।", + "DefaultErrorMessage401": "आप प्रमाणित नहीं हैं!", + "DefaultErrorMessage401Detail": "आपको यह ऑपरेशन करने के लिए साइन इन करना चाहिए।", + "DefaultErrorMessage403": "तुम अधिकृत नहीं हो!", + "DefaultErrorMessage403Detail": "आपको यह ऑपरेशन करने की अनुमति नहीं है!", + "DefaultErrorMessage404": "संसाधन नही मिला!", + "DefaultErrorMessage404Detail": "अनुरोधित संसाधन सर्वर पर नहीं मिला!", + "EntityNotFoundErrorMessage": "Id = {1} के साथ कोई इकाई {0} नहीं है!", + "Error": "त्रुटि", + "UnhandledException": "अनियंत्रित अपवाद!", + "401Message": "अनधिकृत", + "403Message": "मना किया हुआ", + "404Message": "पृष्ठ नहीं मिला", + "500Message": "आंतरिक सर्वर त्रुटि", + "403MessageDetail": "आप इस ऑपरेशन को करने के लिए अधिकृत नहीं हैं!", + "404MessageDetail": "क्षमा करें, इस पते पर कुछ भी नहीं है।" + } +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.ExceptionHandling/Volo/Abp/ExceptionHandling/Localization/it.json b/framework/src/Volo.Abp.ExceptionHandling/Volo/Abp/ExceptionHandling/Localization/it.json new file mode 100644 index 0000000000..b2025559fe --- /dev/null +++ b/framework/src/Volo.Abp.ExceptionHandling/Volo/Abp/ExceptionHandling/Localization/it.json @@ -0,0 +1,25 @@ +{ + "culture": "it", + "texts": { + "InternalServerErrorMessage": "Si è verificato un errore interno durante la tua richiesta!", + "ValidationErrorMessage": "La tua richiesta non è valida!", + "ValidationNarrativeErrorMessageTitle": "Durante la convalida sono stati rilevati i seguenti errori.", + "DefaultErrorMessage": "C'è stato un errore!", + "DefaultErrorMessageDetail": "Dettaglio errore non inviato dal server.", + "DefaultErrorMessage401": "Non sei autenticato!", + "DefaultErrorMessage401Detail": "È necessario accedere per eseguire questa operazione.", + "DefaultErrorMessage403": "Non sei autorizzato!", + "DefaultErrorMessage403Detail": "Non sei autorizzato a eseguire questa operazione!", + "DefaultErrorMessage404": "Risorsa non trovata!", + "DefaultErrorMessage404Detail": "La risorsa richiesta non è stata trovata sul server!", + "EntityNotFoundErrorMessage": "Non esiste un'entità {0} con id = {1}!", + "Error": "Errore", + "UnhandledException": "Eccezione non gestita!", + "401Message": "Non autorizzato", + "403Message": "Vietato", + "404Message": "pagina non trovata", + "500Message": "Errore interno del server", + "403MessageDetail": "Non sei autorizzato a eseguire questa operazione!", + "404MessageDetail": "Spiacenti, non c'è niente a questo indirizzo." + } +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.Features/Volo/Abp/Features/FeatureSimpleStateCheckerExtensions.cs b/framework/src/Volo.Abp.Features/Volo/Abp/Features/FeatureSimpleStateCheckerExtensions.cs new file mode 100644 index 0000000000..d06e55effa --- /dev/null +++ b/framework/src/Volo.Abp.Features/Volo/Abp/Features/FeatureSimpleStateCheckerExtensions.cs @@ -0,0 +1,30 @@ +using JetBrains.Annotations; +using Volo.Abp.SimpleStateChecking; + +namespace Volo.Abp.Features +{ + public static class FeatureSimpleStateCheckerExtensions + { + public static TState RequireFeatures( + [NotNull] this TState state, + params string[] features) + where TState : IHasSimpleStateCheckers + { + state.RequireFeatures(true, features); + return state; + } + + public static TState RequireFeatures( + [NotNull] this TState state, + bool requiresAll, + params string[] features) + where TState : IHasSimpleStateCheckers + { + Check.NotNull(state, nameof(state)); + Check.NotNullOrEmpty(features, nameof(features)); + + state.StateCheckers.Add(new RequireFeaturesSimpleStateChecker(requiresAll, features)); + return state; + } + } +} diff --git a/framework/src/Volo.Abp.Features/Volo/Abp/Features/Localization/hi.json b/framework/src/Volo.Abp.Features/Volo/Abp/Features/Localization/hi.json new file mode 100644 index 0000000000..6137a0417c --- /dev/null +++ b/framework/src/Volo.Abp.Features/Volo/Abp/Features/Localization/hi.json @@ -0,0 +1,8 @@ +{ + "culture": "hi", + "texts": { + "Volo.Feature:010001": "फ़ीचर सक्षम नहीं है: {FeatureName}", + "Volo.Feature:010002": "आवश्यक सुविधाएँ सक्षम नहीं हैं। ये सभी सुविधाएँ सक्षम होनी चाहिए: {FeatureNames}", + "Volo.Feature:010003": "आवश्यक सुविधाएँ सक्षम नहीं हैं। इन विशेषताओं में से कम से कम एक सक्षम होना चाहिए: {FeatureNames}" + } +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.Features/Volo/Abp/Features/Localization/it.json b/framework/src/Volo.Abp.Features/Volo/Abp/Features/Localization/it.json new file mode 100644 index 0000000000..0991d78716 --- /dev/null +++ b/framework/src/Volo.Abp.Features/Volo/Abp/Features/Localization/it.json @@ -0,0 +1,8 @@ +{ + "culture": "it", + "texts": { + "Volo.Feature:010001": "La funzione non è abilitata: {FeatureName}", + "Volo.Feature:010002": "Le funzionalità richieste non sono abilitate. Tutte queste funzioni devono essere abilitate: {FeatureNames}", + "Volo.Feature:010003": "Le funzionalità richieste non sono abilitate. Almeno una di queste funzioni deve essere abilitata: {FeatureNames}" + } +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.Features/Volo/Abp/Features/PermissionDefinitionExtensions.cs b/framework/src/Volo.Abp.Features/Volo/Abp/Features/PermissionDefinitionExtensions.cs deleted file mode 100644 index a213232f2f..0000000000 --- a/framework/src/Volo.Abp.Features/Volo/Abp/Features/PermissionDefinitionExtensions.cs +++ /dev/null @@ -1,28 +0,0 @@ -using JetBrains.Annotations; -using Volo.Abp.Authorization.Permissions; - -namespace Volo.Abp.Features -{ - public static class FeatureDefinitionExtensions - { - public static PermissionDefinition RequireFeatures( - [NotNull] this PermissionDefinition permissionDefinition, - params string[] features) - { - return permissionDefinition.RequireFeatures(true, features); - } - - public static PermissionDefinition RequireFeatures( - [NotNull] this PermissionDefinition permissionDefinition, - bool requiresAll, - params string[] features) - { - Check.NotNull(permissionDefinition, nameof(permissionDefinition)); - Check.NotNullOrEmpty(features, nameof(features)); - - return permissionDefinition.AddStateProviders( - new RequireFeaturesPermissionStateProvider(requiresAll, features) - ); - } - } -} diff --git a/framework/src/Volo.Abp.Features/Volo/Abp/Features/RequireFeaturesPermissionStateProvider.cs b/framework/src/Volo.Abp.Features/Volo/Abp/Features/RequireFeaturesPermissionStateProvider.cs deleted file mode 100644 index 0fee54c598..0000000000 --- a/framework/src/Volo.Abp.Features/Volo/Abp/Features/RequireFeaturesPermissionStateProvider.cs +++ /dev/null @@ -1,32 +0,0 @@ -using System.Threading.Tasks; -using Microsoft.Extensions.DependencyInjection; -using Volo.Abp.Authorization.Permissions; - -namespace Volo.Abp.Features -{ - public class RequireFeaturesPermissionStateProvider : IPermissionStateProvider - { - private readonly string[] _featureNames; - private readonly bool _requiresAll; - - public RequireFeaturesPermissionStateProvider(params string[] featureNames) - : this(true, featureNames) - { - - } - - public RequireFeaturesPermissionStateProvider(bool requiresAll, params string[] featureNames) - { - Check.NotNullOrEmpty(featureNames, nameof(featureNames)); - - _requiresAll = requiresAll; - _featureNames = featureNames; - } - - public async Task IsEnabledAsync(PermissionStateContext context) - { - var feature = context.ServiceProvider.GetRequiredService(); - return await feature.IsEnabledAsync(_requiresAll, _featureNames); - } - } -} diff --git a/framework/src/Volo.Abp.Features/Volo/Abp/Features/RequireFeaturesSimpleStateChecker.cs b/framework/src/Volo.Abp.Features/Volo/Abp/Features/RequireFeaturesSimpleStateChecker.cs new file mode 100644 index 0000000000..1a4c028653 --- /dev/null +++ b/framework/src/Volo.Abp.Features/Volo/Abp/Features/RequireFeaturesSimpleStateChecker.cs @@ -0,0 +1,32 @@ +using System.Threading.Tasks; +using Microsoft.Extensions.DependencyInjection; +using Volo.Abp.SimpleStateChecking; + +namespace Volo.Abp.Features +{ + public class RequireFeaturesSimpleStateChecker : ISimpleStateChecker + where TState : IHasSimpleStateCheckers + { + private readonly string[] _featureNames; + private readonly bool _requiresAll; + + public RequireFeaturesSimpleStateChecker(params string[] featureNames) + : this(true, featureNames) + { + } + + public RequireFeaturesSimpleStateChecker(bool requiresAll, params string[] featureNames) + { + Check.NotNullOrEmpty(featureNames, nameof(featureNames)); + + _requiresAll = requiresAll; + _featureNames = featureNames; + } + + public async Task IsEnabledAsync(SimpleStateCheckerContext context) + { + var featureChecker = context.ServiceProvider.GetRequiredService(); + return await featureChecker.IsEnabledAsync(_requiresAll, _featureNames); + } + } +} diff --git a/framework/src/Volo.Abp.GlobalFeatures/Volo/Abp/GlobalFeatures/GlobalFeatureDefinitionExtensions.cs b/framework/src/Volo.Abp.GlobalFeatures/Volo/Abp/GlobalFeatures/GlobalFeatureDefinitionExtensions.cs deleted file mode 100644 index 299994e695..0000000000 --- a/framework/src/Volo.Abp.GlobalFeatures/Volo/Abp/GlobalFeatures/GlobalFeatureDefinitionExtensions.cs +++ /dev/null @@ -1,50 +0,0 @@ -using System; -using JetBrains.Annotations; -using Volo.Abp.Authorization.Permissions; - -namespace Volo.Abp.GlobalFeatures -{ - public static class GlobalFeatureDefinitionExtensions - { - public static PermissionDefinition RequireGlobalFeatures( - this PermissionDefinition permissionDefinition, - params string[] globalFeatures) - { - return permissionDefinition.RequireGlobalFeatures(true, globalFeatures); - } - - public static PermissionDefinition RequireGlobalFeatures( - [NotNull] this PermissionDefinition permissionDefinition, - bool requiresAll, - params string[] globalFeatures) - { - Check.NotNull(permissionDefinition, nameof(permissionDefinition)); - Check.NotNullOrEmpty(globalFeatures, nameof(globalFeatures)); - - return permissionDefinition.AddStateProviders( - new RequireGlobalFeaturesPermissionStateProvider(requiresAll, globalFeatures) - ); - } - - public static PermissionDefinition RequireGlobalFeatures( - this PermissionDefinition permissionDefinition, - params Type[] globalFeatures) - { - return permissionDefinition.RequireGlobalFeatures(true, globalFeatures); - } - - public static PermissionDefinition RequireGlobalFeatures( - [NotNull] this PermissionDefinition permissionDefinition, - bool requiresAll, - params Type[] globalFeatures) - { - Check.NotNull(permissionDefinition, nameof(permissionDefinition)); - Check.NotNullOrEmpty(globalFeatures, nameof(globalFeatures)); - - return permissionDefinition.AddStateProviders( - new RequireGlobalFeaturesPermissionStateProvider(requiresAll, globalFeatures) - ); - } - - } -} diff --git a/framework/src/Volo.Abp.GlobalFeatures/Volo/Abp/GlobalFeatures/GlobalFeatureSimpleStateCheckerExtensions.cs b/framework/src/Volo.Abp.GlobalFeatures/Volo/Abp/GlobalFeatures/GlobalFeatureSimpleStateCheckerExtensions.cs new file mode 100644 index 0000000000..f18f3d1569 --- /dev/null +++ b/framework/src/Volo.Abp.GlobalFeatures/Volo/Abp/GlobalFeatures/GlobalFeatureSimpleStateCheckerExtensions.cs @@ -0,0 +1,51 @@ +using System; +using JetBrains.Annotations; +using Volo.Abp.SimpleStateChecking; + +namespace Volo.Abp.GlobalFeatures +{ + public static class GlobalFeatureSimpleStateCheckerExtensions + { + public static TState RequireGlobalFeatures( + [NotNull] this TState state, + params string[] globalFeatures) + where TState : IHasSimpleStateCheckers + { + return state.RequireGlobalFeatures(true, globalFeatures); + } + + public static TState RequireGlobalFeatures( + [NotNull] this TState state, + bool requiresAll, + params string[] globalFeatures) + where TState : IHasSimpleStateCheckers + { + Check.NotNull(state, nameof(state)); + Check.NotNullOrEmpty(globalFeatures, nameof(globalFeatures)); + + state.StateCheckers.Add(new RequireGlobalFeaturesSimpleStateChecker(requiresAll, globalFeatures)); + return state; + } + + public static TState RequireGlobalFeatures( + [NotNull] this TState state, + params Type[] globalFeatures) + where TState : IHasSimpleStateCheckers + { + return state.RequireGlobalFeatures(true, globalFeatures); + } + + public static TState RequireGlobalFeatures( + [NotNull] this TState state, + bool requiresAll, + params Type[] globalFeatures) + where TState : IHasSimpleStateCheckers + { + Check.NotNull(state, nameof(state)); + Check.NotNullOrEmpty(globalFeatures, nameof(globalFeatures)); + + state.StateCheckers.Add(new RequireGlobalFeaturesSimpleStateChecker(requiresAll, globalFeatures)); + return state; + } + } +} diff --git a/framework/src/Volo.Abp.GlobalFeatures/Volo/Abp/GlobalFeatures/Localization/hi.json b/framework/src/Volo.Abp.GlobalFeatures/Volo/Abp/GlobalFeatures/Localization/hi.json new file mode 100644 index 0000000000..ca41828fa1 --- /dev/null +++ b/framework/src/Volo.Abp.GlobalFeatures/Volo/Abp/GlobalFeatures/Localization/hi.json @@ -0,0 +1,6 @@ +{ + "culture": "hi", + "texts": { + "Volo.GlobalFeature:010001": "'{ServiceName}' सेवा को '{GlobalFeatureName}' सुविधा को सक्षम करने की आवश्यकता है।" + } +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.GlobalFeatures/Volo/Abp/GlobalFeatures/Localization/it.json b/framework/src/Volo.Abp.GlobalFeatures/Volo/Abp/GlobalFeatures/Localization/it.json new file mode 100644 index 0000000000..21ba5047da --- /dev/null +++ b/framework/src/Volo.Abp.GlobalFeatures/Volo/Abp/GlobalFeatures/Localization/it.json @@ -0,0 +1,6 @@ +{ + "culture": "it", + "texts": { + "Volo.GlobalFeature:010001": "Il servizio \"{ServiceName}\" deve abilitare la funzione \"{GlobalFeatureName}\"." + } +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.GlobalFeatures/Volo/Abp/GlobalFeatures/RequireGlobalFeaturesPermissionStateProvider.cs b/framework/src/Volo.Abp.GlobalFeatures/Volo/Abp/GlobalFeatures/RequireGlobalFeaturesSimpleStateChecker.cs similarity index 61% rename from framework/src/Volo.Abp.GlobalFeatures/Volo/Abp/GlobalFeatures/RequireGlobalFeaturesPermissionStateProvider.cs rename to framework/src/Volo.Abp.GlobalFeatures/Volo/Abp/GlobalFeatures/RequireGlobalFeaturesSimpleStateChecker.cs index c96e652e8c..12754d87df 100644 --- a/framework/src/Volo.Abp.GlobalFeatures/Volo/Abp/GlobalFeatures/RequireGlobalFeaturesPermissionStateProvider.cs +++ b/framework/src/Volo.Abp.GlobalFeatures/Volo/Abp/GlobalFeatures/RequireGlobalFeaturesSimpleStateChecker.cs @@ -1,21 +1,22 @@ using System; using System.Linq; using System.Threading.Tasks; -using Volo.Abp.Authorization.Permissions; +using Volo.Abp.SimpleStateChecking; namespace Volo.Abp.GlobalFeatures { - public class RequireGlobalFeaturesPermissionStateProvider : IPermissionStateProvider + public class RequireGlobalFeaturesSimpleStateChecker : ISimpleStateChecker + where TState : IHasSimpleStateCheckers { private readonly string[] _globalFeatureNames; private readonly bool _requiresAll; - public RequireGlobalFeaturesPermissionStateProvider(params string[] globalFeatureNames) + public RequireGlobalFeaturesSimpleStateChecker(params string[] globalFeatureNames) : this(true, globalFeatureNames) { } - public RequireGlobalFeaturesPermissionStateProvider(bool requiresAll, params string[] globalFeatureNames) + public RequireGlobalFeaturesSimpleStateChecker(bool requiresAll, params string[] globalFeatureNames) { Check.NotNullOrEmpty(globalFeatureNames, nameof(globalFeatureNames)); @@ -23,7 +24,7 @@ namespace Volo.Abp.GlobalFeatures _globalFeatureNames = globalFeatureNames; } - public RequireGlobalFeaturesPermissionStateProvider(bool requiresAll, params Type[] globalFeatureNames) + public RequireGlobalFeaturesSimpleStateChecker(bool requiresAll, params Type[] globalFeatureNames) { Check.NotNullOrEmpty(globalFeatureNames, nameof(globalFeatureNames)); @@ -31,9 +32,9 @@ namespace Volo.Abp.GlobalFeatures _globalFeatureNames = globalFeatureNames.Select(GlobalFeatureNameAttribute.GetName).ToArray(); } - public Task IsEnabledAsync(PermissionStateContext context) + public Task IsEnabledAsync(SimpleStateCheckerContext context) { - bool isEnabled = _requiresAll + var isEnabled = _requiresAll ? _globalFeatureNames.All(x => GlobalFeatureManager.Instance.IsEnabled(x)) : _globalFeatureNames.Any(x => GlobalFeatureManager.Instance.IsEnabled(x)); diff --git a/framework/src/Volo.Abp.Http.Client.IdentityModel.WebAssembly/Volo/Abp/Http/Client/IdentityModel/WebAssembly/AccessTokenProviderIdentityModelRemoteServiceHttpClientAuthenticator.cs b/framework/src/Volo.Abp.Http.Client.IdentityModel.WebAssembly/Volo/Abp/Http/Client/IdentityModel/WebAssembly/AccessTokenProviderIdentityModelRemoteServiceHttpClientAuthenticator.cs index c86fc095c7..3f74918d98 100644 --- a/framework/src/Volo.Abp.Http.Client.IdentityModel.WebAssembly/Volo/Abp/Http/Client/IdentityModel/WebAssembly/AccessTokenProviderIdentityModelRemoteServiceHttpClientAuthenticator.cs +++ b/framework/src/Volo.Abp.Http.Client.IdentityModel.WebAssembly/Volo/Abp/Http/Client/IdentityModel/WebAssembly/AccessTokenProviderIdentityModelRemoteServiceHttpClientAuthenticator.cs @@ -1,6 +1,9 @@ -using System.Threading.Tasks; +using System; +using System.Threading.Tasks; using IdentityModel.Client; +using JetBrains.Annotations; using Microsoft.AspNetCore.Components.WebAssembly.Authentication; +using Microsoft.Extensions.DependencyInjection; using Volo.Abp.DependencyInjection; using Volo.Abp.Http.Client.Authentication; using Volo.Abp.IdentityModel; @@ -8,16 +11,18 @@ using Volo.Abp.IdentityModel; namespace Volo.Abp.Http.Client.IdentityModel.WebAssembly { [Dependency(ReplaceServices = true)] - public class AccessTokenProviderIdentityModelRemoteServiceHttpClientAuthenticator : IdentityModelRemoteServiceHttpClientAuthenticator + public class AccessTokenProviderIdentityModelRemoteServiceHttpClientAuthenticator + : IdentityModelRemoteServiceHttpClientAuthenticator { + [CanBeNull] protected IAccessTokenProvider AccessTokenProvider { get; } public AccessTokenProviderIdentityModelRemoteServiceHttpClientAuthenticator( IIdentityModelAuthenticationService identityModelAuthenticationService, - IAccessTokenProvider accessTokenProvider) + IServiceProvider serviceProvider) : base(identityModelAuthenticationService) { - AccessTokenProvider = accessTokenProvider; + AccessTokenProvider = serviceProvider.GetService(); } public override async Task Authenticate(RemoteServiceHttpClientAuthenticateContext context) @@ -37,6 +42,11 @@ namespace Volo.Abp.Http.Client.IdentityModel.WebAssembly protected virtual async Task GetAccessTokenFromAccessTokenProviderOrNullAsync() { + if (AccessTokenProvider == null) + { + return null; + } + var result = await AccessTokenProvider.RequestAccessToken(); if (result.Status != AccessTokenResultStatus.Success) { diff --git a/framework/src/Volo.Abp.Ldap/Volo/Abp/Ldap/Localization/hi.json b/framework/src/Volo.Abp.Ldap/Volo/Abp/Ldap/Localization/hi.json new file mode 100644 index 0000000000..b466bdb570 --- /dev/null +++ b/framework/src/Volo.Abp.Ldap/Volo/Abp/Ldap/Localization/hi.json @@ -0,0 +1,15 @@ +{ + "culture": "hi", + "texts": { + "DisplayName:Abp.Ldap.ServerHost": "सर्वर होस्ट", + "Description:Abp.Ldap.ServerHost": "सर्वर होस्ट", + "DisplayName:Abp.Ldap.ServerPort": "सर्वर पोर्ट", + "Description:Abp.Ldap.ServerPort": "सर्वर पोर्ट", + "DisplayName:Abp.Ldap.BaseDc": "बेस डोमेन घटक", + "Description:Abp.Ldap.BaseDc": "बेस डोमेन घटक", + "DisplayName:Abp.Ldap.UserName": "उपयोगकर्ता नाम", + "Description:Abp.Ldap.UserName": "उपयोगकर्ता नाम", + "DisplayName:Abp.Ldap.Password": "कुंजिका", + "Description:Abp.Ldap.Password": "कुंजिका" + } +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.Ldap/Volo/Abp/Ldap/Localization/it.json b/framework/src/Volo.Abp.Ldap/Volo/Abp/Ldap/Localization/it.json new file mode 100644 index 0000000000..61fd573b09 --- /dev/null +++ b/framework/src/Volo.Abp.Ldap/Volo/Abp/Ldap/Localization/it.json @@ -0,0 +1,15 @@ +{ + "culture": "it", + "texts": { + "DisplayName:Abp.Ldap.ServerHost": "Host del server", + "Description:Abp.Ldap.ServerHost": "Host del server", + "DisplayName:Abp.Ldap.ServerPort": "Porta del server", + "Description:Abp.Ldap.ServerPort": "Porta del server", + "DisplayName:Abp.Ldap.BaseDc": "Componente del dominio di base", + "Description:Abp.Ldap.BaseDc": "Componente del dominio di base", + "DisplayName:Abp.Ldap.UserName": "Nome utente", + "Description:Abp.Ldap.UserName": "Nome utente", + "DisplayName:Abp.Ldap.Password": "Parola d'ordine", + "Description:Abp.Ldap.Password": "Parola d'ordine" + } +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.Localization/Volo/Abp/Localization/Resources/AbpLocalization/hi.json b/framework/src/Volo.Abp.Localization/Volo/Abp/Localization/Resources/AbpLocalization/hi.json new file mode 100644 index 0000000000..fe3bb7f4ce --- /dev/null +++ b/framework/src/Volo.Abp.Localization/Volo/Abp/Localization/Resources/AbpLocalization/hi.json @@ -0,0 +1,7 @@ +{ + "culture": "hi", + "texts": { + "DisplayName:Abp.Localization.DefaultLanguage": "डिफ़ॉल्ट भाषा", + "Description:Abp.Localization.DefaultLanguage": "एप्लिकेशन की डिफ़ॉल्ट भाषा।" + } +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.Localization/Volo/Abp/Localization/Resources/AbpLocalization/it.json b/framework/src/Volo.Abp.Localization/Volo/Abp/Localization/Resources/AbpLocalization/it.json new file mode 100644 index 0000000000..f42a817943 --- /dev/null +++ b/framework/src/Volo.Abp.Localization/Volo/Abp/Localization/Resources/AbpLocalization/it.json @@ -0,0 +1,7 @@ +{ + "culture": "it", + "texts": { + "DisplayName:Abp.Localization.DefaultLanguage": "Lingua di default", + "Description:Abp.Localization.DefaultLanguage": "La lingua predefinita dell'applicazione." + } +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.MongoDB/Microsoft/Extensions/DependencyInjection/AbpMongoDbServiceCollectionExtensions.cs b/framework/src/Volo.Abp.MongoDB/Microsoft/Extensions/DependencyInjection/AbpMongoDbServiceCollectionExtensions.cs index 5adf7300ee..7f9c6b8d42 100644 --- a/framework/src/Volo.Abp.MongoDB/Microsoft/Extensions/DependencyInjection/AbpMongoDbServiceCollectionExtensions.cs +++ b/framework/src/Volo.Abp.MongoDB/Microsoft/Extensions/DependencyInjection/AbpMongoDbServiceCollectionExtensions.cs @@ -1,5 +1,8 @@ using System; +using System.Linq; +using System.Reflection; using Microsoft.Extensions.DependencyInjection.Extensions; +using Volo.Abp.DependencyInjection; using Volo.Abp.MongoDB; using Volo.Abp.MongoDB.DependencyInjection; @@ -11,13 +14,22 @@ namespace Microsoft.Extensions.DependencyInjection where TMongoDbContext : AbpMongoDbContext { var options = new AbpMongoDbContextRegistrationOptions(typeof(TMongoDbContext), services); + + var replacedDbContextTypes = typeof(TMongoDbContext).GetCustomAttributes(true) + .SelectMany( x => x.ReplacedDbContextTypes).ToList(); + + foreach (var dbContextType in replacedDbContextTypes) + { + options.ReplaceDbContext(dbContextType); + } + optionsBuilder?.Invoke(options); foreach (var dbContextType in options.ReplacedDbContextTypes) { services.Replace(ServiceDescriptor.Transient(dbContextType, typeof(TMongoDbContext))); } - + foreach (var dbContextType in options.ReplacedDbContextTypes) { services.Replace( diff --git a/framework/src/Volo.Abp.MongoDB/Volo/Abp/MongoDB/DependencyInjection/AbpMongoDbConventionalRegistrar.cs b/framework/src/Volo.Abp.MongoDB/Volo/Abp/MongoDB/DependencyInjection/AbpMongoDbConventionalRegistrar.cs index cb1ed7ea54..e0a6265f7c 100644 --- a/framework/src/Volo.Abp.MongoDB/Volo/Abp/MongoDB/DependencyInjection/AbpMongoDbConventionalRegistrar.cs +++ b/framework/src/Volo.Abp.MongoDB/Volo/Abp/MongoDB/DependencyInjection/AbpMongoDbConventionalRegistrar.cs @@ -1,5 +1,7 @@ using System; +using System.Reflection; using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.DependencyInjection.Extensions; using Volo.Abp.DependencyInjection; namespace Volo.Abp.MongoDB.DependencyInjection diff --git a/framework/src/Volo.Abp.MongoDB/Volo/Abp/Uow/MongoDB/UnitOfWorkMongoDbContextProvider.cs b/framework/src/Volo.Abp.MongoDB/Volo/Abp/Uow/MongoDB/UnitOfWorkMongoDbContextProvider.cs index a26307234d..2a3842441f 100644 --- a/framework/src/Volo.Abp.MongoDB/Volo/Abp/Uow/MongoDB/UnitOfWorkMongoDbContextProvider.cs +++ b/framework/src/Volo.Abp.MongoDB/Volo/Abp/Uow/MongoDB/UnitOfWorkMongoDbContextProvider.cs @@ -62,8 +62,8 @@ namespace Volo.Abp.Uow.MongoDB $"A {nameof(IMongoDatabase)} instance can only be created inside a unit of work!"); } - var connectionString = ResolveConnectionString(); var targetDbContextType = _options.GetReplacedTypeOrSelf(typeof(TMongoDbContext)); + var connectionString = ResolveConnectionString(targetDbContextType); var dbContextKey = $"{targetDbContextType.FullName}_{connectionString}"; var mongoUrl = new MongoUrl(connectionString); @@ -90,8 +90,8 @@ namespace Volo.Abp.Uow.MongoDB $"A {nameof(IMongoDatabase)} instance can only be created inside a unit of work!"); } - var connectionString = await ResolveConnectionStringAsync(); var targetDbContextType = _options.GetReplacedTypeOrSelf(typeof(TMongoDbContext)); + var connectionString = await ResolveConnectionStringAsync(targetDbContextType); var dbContextKey = $"{targetDbContextType.FullName}_{connectionString}"; var mongoUrl = new MongoUrl(connectionString); @@ -244,33 +244,33 @@ namespace Volo.Abp.Uow.MongoDB return dbContext; } - private async Task ResolveConnectionStringAsync() + private async Task ResolveConnectionStringAsync(Type dbContextType) { // Multi-tenancy unaware contexts should always use the host connection string if (typeof(TMongoDbContext).IsDefined(typeof(IgnoreMultiTenancyAttribute), false)) { using (_currentTenant.Change(null)) { - return await _connectionStringResolver.ResolveAsync(); + return await _connectionStringResolver.ResolveAsync(dbContextType); } } - return await _connectionStringResolver.ResolveAsync(); + return await _connectionStringResolver.ResolveAsync(dbContextType); } [Obsolete("Use ResolveConnectionStringAsync method.")] - private string ResolveConnectionString() + private string ResolveConnectionString(Type dbContextType) { // Multi-tenancy unaware contexts should always use the host connection string if (typeof(TMongoDbContext).IsDefined(typeof(IgnoreMultiTenancyAttribute), false)) { using (_currentTenant.Change(null)) { - return _connectionStringResolver.Resolve(); + return _connectionStringResolver.Resolve(dbContextType); } } - return _connectionStringResolver.Resolve(); + return _connectionStringResolver.Resolve(dbContextType); } protected virtual CancellationToken GetCancellationToken(CancellationToken preferredValue = default) diff --git a/framework/src/Volo.Abp.MultiTenancy/Volo/Abp/MultiTenancy/TenantConfiguration.cs b/framework/src/Volo.Abp.MultiTenancy/Volo/Abp/MultiTenancy/TenantConfiguration.cs index e586e687c3..35b3a0e52e 100644 --- a/framework/src/Volo.Abp.MultiTenancy/Volo/Abp/MultiTenancy/TenantConfiguration.cs +++ b/framework/src/Volo.Abp.MultiTenancy/Volo/Abp/MultiTenancy/TenantConfiguration.cs @@ -13,12 +13,15 @@ namespace Volo.Abp.MultiTenancy public ConnectionStrings ConnectionStrings { get; set; } + public bool IsActive { get; set; } + public TenantConfiguration() { - + IsActive = true; } public TenantConfiguration(Guid id, [NotNull] string name) + : this() { Check.NotNull(name, nameof(name)); diff --git a/framework/src/Volo.Abp.MultiTenancy/Volo/Abp/MultiTenancy/TenantConfigurationProvider.cs b/framework/src/Volo.Abp.MultiTenancy/Volo/Abp/MultiTenancy/TenantConfigurationProvider.cs index 81a9c72042..1c3223828d 100644 --- a/framework/src/Volo.Abp.MultiTenancy/Volo/Abp/MultiTenancy/TenantConfigurationProvider.cs +++ b/framework/src/Volo.Abp.MultiTenancy/Volo/Abp/MultiTenancy/TenantConfigurationProvider.cs @@ -42,6 +42,15 @@ namespace Volo.Abp.MultiTenancy details: "There is no tenant with the tenant id or name: " + resolveResult.TenantIdOrName ); } + + if (!tenant.IsActive) + { + throw new BusinessException( + code: "Volo.AbpIo.MultiTenancy:010002", + message: "Tenant not active!", + details: "The tenant is no active with the tenant id or name: " + resolveResult.TenantIdOrName + ); + } } return tenant; diff --git a/framework/src/Volo.Abp.ObjectExtending/Volo/Abp/ObjectExtending/ObjectExtensionInfo.cs b/framework/src/Volo.Abp.ObjectExtending/Volo/Abp/ObjectExtending/ObjectExtensionInfo.cs index 18b3c2c73d..5f653fd92c 100644 --- a/framework/src/Volo.Abp.ObjectExtending/Volo/Abp/ObjectExtending/ObjectExtensionInfo.cs +++ b/framework/src/Volo.Abp.ObjectExtending/Volo/Abp/ObjectExtending/ObjectExtensionInfo.cs @@ -2,6 +2,7 @@ using System.Collections.Concurrent; using System.Collections.Generic; using System.Collections.Immutable; +using System.Linq; using JetBrains.Annotations; using Volo.Abp.Data; @@ -68,7 +69,9 @@ namespace Volo.Abp.ObjectExtending [NotNull] public virtual ImmutableList GetProperties() { - return Properties.Values.ToImmutableList(); + return Properties.OrderBy(t=>t.Key) + .Select(t=>t.Value) + .ToImmutableList(); } [CanBeNull] diff --git a/framework/src/Volo.Abp.RabbitMQ/Volo/Abp/RabbitMQ/ConnectionPool.cs b/framework/src/Volo.Abp.RabbitMQ/Volo/Abp/RabbitMQ/ConnectionPool.cs index c227d978a1..a7dca73646 100644 --- a/framework/src/Volo.Abp.RabbitMQ/Volo/Abp/RabbitMQ/ConnectionPool.cs +++ b/framework/src/Volo.Abp.RabbitMQ/Volo/Abp/RabbitMQ/ConnectionPool.cs @@ -25,16 +25,26 @@ namespace Volo.Abp.RabbitMQ { connectionName ??= RabbitMqConnections.DefaultConnectionName; - return Connections.GetOrAdd( - connectionName, () => new Lazy(() => - { - var connection = Options.Connections.GetOrDefault(connectionName); - var hostnames = connection.HostName.TrimEnd(';').Split(';'); - // Handle Rabbit MQ Cluster. - return hostnames.Length == 1 ? connection.CreateConnection() : connection.CreateConnection(hostnames); + try + { + var lazyConnection = Connections.GetOrAdd( + connectionName, () => new Lazy(() => + { + var connection = Options.Connections.GetOrDefault(connectionName); + var hostnames = connection.HostName.TrimEnd(';').Split(';'); + // Handle Rabbit MQ Cluster. + return hostnames.Length == 1 ? connection.CreateConnection() : connection.CreateConnection(hostnames); + + }) + ); - }) - ).Value; + return lazyConnection.Value; + } + catch (Exception) + { + Connections.TryRemove(connectionName, out _); + throw; + } } public void Dispose() diff --git a/framework/src/Volo.Abp.Timing/Volo/Abp/Timing/Localization/hi.json b/framework/src/Volo.Abp.Timing/Volo/Abp/Timing/Localization/hi.json new file mode 100644 index 0000000000..8878cf64d9 --- /dev/null +++ b/framework/src/Volo.Abp.Timing/Volo/Abp/Timing/Localization/hi.json @@ -0,0 +1,7 @@ +{ + "culture": "hi", + "texts": { + "DisplayName:Abp.Timing.Timezone": "समय क्षेत्र", + "Description:Abp.Timing.Timezone": "आवेदन समय क्षेत्र" + } +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.Timing/Volo/Abp/Timing/Localization/it.json b/framework/src/Volo.Abp.Timing/Volo/Abp/Timing/Localization/it.json new file mode 100644 index 0000000000..107f1ebb3b --- /dev/null +++ b/framework/src/Volo.Abp.Timing/Volo/Abp/Timing/Localization/it.json @@ -0,0 +1,7 @@ +{ + "culture": "it", + "texts": { + "DisplayName:Abp.Timing.Timezone": "Fuso orario", + "Description:Abp.Timing.Timezone": "Fuso orario dell'applicazione" + } +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.UI.Navigation/Volo/Abp/Ui/Navigation/ApplicationMenuItem.cs b/framework/src/Volo.Abp.UI.Navigation/Volo/Abp/Ui/Navigation/ApplicationMenuItem.cs index 63f4d7239d..f269c34598 100644 --- a/framework/src/Volo.Abp.UI.Navigation/Volo/Abp/Ui/Navigation/ApplicationMenuItem.cs +++ b/framework/src/Volo.Abp.UI.Navigation/Volo/Abp/Ui/Navigation/ApplicationMenuItem.cs @@ -1,10 +1,11 @@ using System; using System.Collections.Generic; using JetBrains.Annotations; +using Volo.Abp.SimpleStateChecking; namespace Volo.Abp.UI.Navigation { - public class ApplicationMenuItem : IHasMenuItems + public class ApplicationMenuItem : IHasMenuItems, IHasSimpleStateCheckers { private string _displayName; @@ -72,8 +73,11 @@ namespace Volo.Abp.UI.Navigation public ApplicationMenuItemList Items { get; } [CanBeNull] + [Obsolete("Use RequirePermissions extension method.")] public string RequiredPermissionName { get; set; } + public List> StateCheckers { get; } + /// /// Can be used to store a custom object related to this menu item. Optional. /// @@ -114,7 +118,7 @@ namespace Volo.Abp.UI.Navigation ElementId = elementId ?? GetDefaultElementId(); CssClass = cssClass; RequiredPermissionName = requiredPermissionName; - + StateCheckers = new List>(); Items = new ApplicationMenuItemList(); } diff --git a/framework/src/Volo.Abp.UI.Navigation/Volo/Abp/Ui/Navigation/Localization/Resource/hi.json b/framework/src/Volo.Abp.UI.Navigation/Volo/Abp/Ui/Navigation/Localization/Resource/hi.json new file mode 100644 index 0000000000..6b9ac8ab4c --- /dev/null +++ b/framework/src/Volo.Abp.UI.Navigation/Volo/Abp/Ui/Navigation/Localization/Resource/hi.json @@ -0,0 +1,6 @@ +{ + "culture": "hi", + "texts": { + "Menu:Administration": "शासन प्रबंध" + } +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.UI.Navigation/Volo/Abp/Ui/Navigation/Localization/Resource/it.json b/framework/src/Volo.Abp.UI.Navigation/Volo/Abp/Ui/Navigation/Localization/Resource/it.json new file mode 100644 index 0000000000..d8a21ec090 --- /dev/null +++ b/framework/src/Volo.Abp.UI.Navigation/Volo/Abp/Ui/Navigation/Localization/Resource/it.json @@ -0,0 +1,6 @@ +{ + "culture": "it", + "texts": { + "Menu:Administration": "Amministrazione" + } +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.UI.Navigation/Volo/Abp/Ui/Navigation/MenuManager.cs b/framework/src/Volo.Abp.UI.Navigation/Volo/Abp/Ui/Navigation/MenuManager.cs index 960389230e..0b52aff7b8 100644 --- a/framework/src/Volo.Abp.UI.Navigation/Volo/Abp/Ui/Navigation/MenuManager.cs +++ b/framework/src/Volo.Abp.UI.Navigation/Volo/Abp/Ui/Navigation/MenuManager.cs @@ -2,10 +2,10 @@ using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; -using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Options; using Volo.Abp.Authorization.Permissions; using Volo.Abp.DependencyInjection; +using Volo.Abp.SimpleStateChecking; namespace Volo.Abp.UI.Navigation { @@ -13,13 +13,15 @@ namespace Volo.Abp.UI.Navigation { protected AbpNavigationOptions Options { get; } protected IHybridServiceScopeFactory ServiceScopeFactory { get; } - + protected ISimpleStateCheckerManager SimpleStateCheckerManager { get; } public MenuManager( IOptions options, - IHybridServiceScopeFactory serviceScopeFactory) + IHybridServiceScopeFactory serviceScopeFactory, + ISimpleStateCheckerManager simpleStateCheckerManager) { - ServiceScopeFactory = serviceScopeFactory; Options = options.Value; + ServiceScopeFactory = serviceScopeFactory; + SimpleStateCheckerManager = simpleStateCheckerManager; } public async Task GetAsync(string name) @@ -28,14 +30,17 @@ namespace Volo.Abp.UI.Navigation using (var scope = ServiceScopeFactory.CreateScope()) { - var context = new MenuConfigurationContext(menu, scope.ServiceProvider); - - foreach (var contributor in Options.MenuContributors) + using (RequirePermissionsSimpleBatchStateChecker.Use(new RequirePermissionsSimpleBatchStateChecker())) { - await contributor.ConfigureMenuAsync(context); - } + var context = new MenuConfigurationContext(menu, scope.ServiceProvider); - await CheckPermissionsAsync(scope.ServiceProvider, menu); + foreach (var contributor in Options.MenuContributors) + { + await contributor.ConfigureMenuAsync(context); + } + + await CheckPermissionsAsync(scope.ServiceProvider, menu); + } } NormalizeMenu(menu); @@ -45,18 +50,26 @@ namespace Volo.Abp.UI.Navigation protected virtual async Task CheckPermissionsAsync(IServiceProvider serviceProvider, IHasMenuItems menuWithItems) { - var requiredPermissionItems = new List(); - GetRequiredPermissionNameMenus(menuWithItems, requiredPermissionItems); + var allMenuItems = new List(); + GetAllMenuItems(menuWithItems, allMenuItems); - if (requiredPermissionItems.Any()) + foreach (var item in allMenuItems) { - var permissionChecker = serviceProvider.GetRequiredService(); - var grantResult = await permissionChecker.IsGrantedAsync(requiredPermissionItems.Select(x => x.RequiredPermissionName).Distinct().ToArray()); + if (!item.RequiredPermissionName.IsNullOrWhiteSpace()) + { + item.RequirePermissions(item.RequiredPermissionName); + } + } + var checkPermissionsMenuItems = allMenuItems.Where(x => x.StateCheckers.Any()).ToArray(); + + if (checkPermissionsMenuItems.Any()) + { var toBeDeleted = new HashSet(); - foreach (var menu in requiredPermissionItems) + var result = await SimpleStateCheckerManager.IsEnabledAsync(checkPermissionsMenuItems); + foreach (var menu in checkPermissionsMenuItems) { - if (grantResult.Result[menu.RequiredPermissionName!] != PermissionGrantResult.Granted) + if (!result[menu]) { toBeDeleted.Add(menu); } @@ -66,16 +79,12 @@ namespace Volo.Abp.UI.Navigation } } - protected virtual void GetRequiredPermissionNameMenus(IHasMenuItems menuWithItems, List output) + protected virtual void GetAllMenuItems(IHasMenuItems menuWithItems, List output) { foreach (var item in menuWithItems.Items) { - if (!item.RequiredPermissionName.IsNullOrWhiteSpace()) - { - output.Add(item); - } - - GetRequiredPermissionNameMenus(item, output); + output.Add(item); + GetAllMenuItems(item, output); } } diff --git a/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/es.json b/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/es.json index 076d4b2517..ff846b3f18 100644 --- a/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/es.json +++ b/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/es.json @@ -11,7 +11,7 @@ "Close": "Cerrar", "Save": "Guardar", "SavingWithThreeDot": "Guardando...", - "Actions": "Acciones", + "Actions": "Opciones", "Delete": "Borrar", "Edit": "Editar", "Refresh": "Actualizar", @@ -20,10 +20,10 @@ "ProcessingWithThreeDot": "Procesando...", "LoadingWithThreeDot": "Cargardo...", "Welcome": "Bienvenido", - "Login": "Iniciar Sesión", + "Login": "Iniciar sesión", "Register": "Registrarse", "Logout": "Cerrar sesión", - "Submit": "Enviar", + "Submit": "Guardar", "Back": "Volver", "PagerSearch": "Buscar", "PagerNext": "Siguiente", @@ -37,11 +37,11 @@ "NoDataAvailableInDatatable": "No hay datos disponibles", "Total": "Total", "Selected": "Seleccionado", - "PagerShowMenuEntries": "Mostrar _MENU_ entradas", - "DatatableActionDropdownDefaultText": "Acciones", + "PagerShowMenuEntries": "Mostrar _MENU_ registros", + "DatatableActionDropdownDefaultText": "Opciones", "ChangePassword": "Cambiar contraseña", "PersonalInfo": "Mi perfil", - "AreYouSureYouWantToCancelEditingWarningMessage": "Tu tienes cambios sin guardar", + "AreYouSureYouWantToCancelEditingWarningMessage": "Tienes cambios sin guardar", "GoHomePage": "Ir a la página principal", "GoBack": "Volver atrás", "Search": "Buscar", diff --git a/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/hi.json b/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/hi.json new file mode 100644 index 0000000000..7fbdb1375a --- /dev/null +++ b/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/hi.json @@ -0,0 +1,52 @@ +{ + "culture": "hi", + "texts": { + "Languages": "बोली", + "AreYouSure": "क्या आपको यकीन है?", + "Cancel": "रद्द करना", + "Clear": "स्पष्ट", + "Yes": "हाँ", + "No": "नहीं न", + "Ok": "ठीक है", + "Close": "बंद करे", + "Save": "सहेजें", + "SavingWithThreeDot": "सहेजा जा रहा है ...", + "Actions": "कार्रवाई", + "Delete": "हटाएं", + "Edit": "संपादित करें", + "Refresh": "ताज़ा करना", + "Language": "भाषा: हिन्दी", + "LoadMore": "और लोड करें", + "ProcessingWithThreeDot": "प्रसंस्करण ...", + "LoadingWithThreeDot": "लोड हो रहा है...", + "Welcome": "स्वागत हे", + "Login": "लॉग इन करें", + "Register": "रजिस्टर करें", + "Logout": "लॉग आउट", + "Submit": "प्रस्तुत", + "Back": "वापस", + "PagerSearch": "खोज", + "PagerNext": "अगला", + "PagerPrevious": "पहले का", + "PagerFirst": "प्रथम", + "PagerLast": "पिछले", + "PagerInfo": "_TARTAL_ प्रविष्टियों में से _START_ से _END_ दिखा रहा है", + "PagerInfo{0}{1}{2}": "{2} प्रविष्टियों में {0} से {1} दिखा रहा है", + "PagerInfoEmpty": "0 से 0 प्रविष्टियों को दिखा रहा है", + "PagerInfoFiltered": "(_MAX_ कुल प्रविष्टियों से फ़िल्टर किया गया)", + "NoDataAvailableInDatatable": "कोई डेटा उपलब्ध नहीं है", + "Total": "संपूर्ण", + "Selected": "चयनित", + "PagerShowMenuEntries": "_MENU_ प्रविष्टियाँ दिखाएँ", + "DatatableActionDropdownDefaultText": "कार्रवाई", + "ChangePassword": "पासवर्ड बदलें", + "PersonalInfo": "मेरी प्रोफाइल", + "AreYouSureYouWantToCancelEditingWarningMessage": "आपके पास सहेजे नहीं गए परिवर्तन हैं।", + "GoHomePage": "होम पेज़ पर जाएं", + "GoBack": "वापस जाओ", + "Search": "खोज", + "ItemWillBeDeletedMessageWithFormat": "{0} हटा दिया जाएगा!", + "ItemWillBeDeletedMessage": "यह आइटम हटा दिया जाएगा!", + "ManageYourAccount": "अपने खाते का प्रबंधन" + } +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/it.json b/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/it.json new file mode 100644 index 0000000000..6a66828c6e --- /dev/null +++ b/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/it.json @@ -0,0 +1,52 @@ +{ + "culture": "it", + "texts": { + "Languages": "Le lingue", + "AreYouSure": "Sei sicuro?", + "Cancel": "Annulla", + "Clear": "Chiaro", + "Yes": "sì", + "No": "No", + "Ok": "Ok", + "Close": "Vicino", + "Save": "Salva", + "SavingWithThreeDot": "Salvataggio...", + "Actions": "Azioni", + "Delete": "Elimina", + "Edit": "modificare", + "Refresh": "ricaricare", + "Language": "linguaggio", + "LoadMore": "Carica di più", + "ProcessingWithThreeDot": "In lavorazione...", + "LoadingWithThreeDot": "Caricamento in corso...", + "Welcome": "benvenuto", + "Login": "Login", + "Register": "Registrati", + "Logout": "Disconnettersi", + "Submit": "Invia", + "Back": "Indietro", + "PagerSearch": "Ricerca", + "PagerNext": "Il prossimo", + "PagerPrevious": "Precedente", + "PagerFirst": "Primo", + "PagerLast": "Scorso", + "PagerInfo": "Visualizzazione da _START_ a _END_ di _TOTAL_ voci", + "PagerInfo{0}{1}{2}": "Visualizzazione da {0} a {1} di {2} voci", + "PagerInfoEmpty": "Mostra da 0 a 0 di 0 voci", + "PagerInfoFiltered": "(filtrato da _MAX_ voci totali)", + "NoDataAvailableInDatatable": "Nessun dato disponibile", + "Total": "totale", + "Selected": "selezionato", + "PagerShowMenuEntries": "Mostra voci _MENU_", + "DatatableActionDropdownDefaultText": "Azioni", + "ChangePassword": "Cambia la password", + "PersonalInfo": "Il mio profilo", + "AreYouSureYouWantToCancelEditingWarningMessage": "Hai modifiche non salvate.", + "GoHomePage": "Vai alla home page", + "GoBack": "Torna indietro", + "Search": "Ricerca", + "ItemWillBeDeletedMessageWithFormat": "{0} verrà eliminato!", + "ItemWillBeDeletedMessage": "Questo articolo sarà eliminato!", + "ManageYourAccount": "Gestire il tuo account" + } +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.Validation/Volo/Abp/Validation/Localization/hi.json b/framework/src/Volo.Abp.Validation/Volo/Abp/Validation/Localization/hi.json new file mode 100644 index 0000000000..fab1a394b4 --- /dev/null +++ b/framework/src/Volo.Abp.Validation/Volo/Abp/Validation/Localization/hi.json @@ -0,0 +1,34 @@ +{ + "culture": "hi", + "texts": { + "'{0}' and '{1}' do not match.": "'{0}' और '{1}' मेल नहीं खाते।", + "The {0} field is not a valid credit card number.": "{0} फ़ील्ड मान्य क्रेडिट कार्ड नंबर नहीं है।", + "{0} is not valid.": "{0} मान्य नहीं है।", + "The {0} field is not a valid e-mail address.": "{0} फ़ील्ड मान्य ई-मेल पता नहीं है।", + "The {0} field only accepts files with the following extensions: {1}": "{0} फ़ील्ड केवल निम्नलिखित एक्सटेंशन वाली फाइलें स्वीकार करती है: {1}", + "The field {0} must be a string or array type with a maximum length of '{1}'.": "फ़ील्ड {0} एक स्ट्रिंग या सरणी प्रकार होना चाहिए जिसकी अधिकतम लंबाई '{1}' हो।", + "The field {0} must be a string or array type with a minimum length of '{1}'.": "फ़ील्ड {0} में '{1}' की न्यूनतम लंबाई के साथ एक स्ट्रिंग या सरणी प्रकार होना चाहिए।", + "The {0} field is not a valid phone number.": "{0} फ़ील्ड एक मान्य फ़ोन नंबर नहीं है।", + "The field {0} must be between {1} and {2}.": "फ़ील्ड {0} को {1} और {2} के बीच होना चाहिए।", + "The field {0} must match the regular expression '{1}'.": "फ़ील्ड {0} अनुरोधित प्रारूप से मेल नहीं खाती है।", + "The {0} field is required.": "{0} फ़ील्ड आवश्यक है।", + "The field {0} must be a string with a maximum length of {1}.": "फ़ील्ड {0} की लंबाई अधिकतम लंबाई के साथ होनी चाहिए {1}।", + "The field {0} must be a string with a minimum length of {2} and a maximum length of {1}.": "फ़ील्ड {0} की लंबाई न्यूनतम {2} और अधिकतम लंबाई {1} होनी चाहिए।", + "The {0} field is not a valid fully-qualified http, https, or ftp URL.": "{0} फ़ील्ड मान्य पूर्णत: योग्य http, https, या ftp URL नहीं है।", + "The field {0} is invalid.": "फ़ील्ड {0} अमान्य है।", + "ThisFieldIsNotAValidCreditCardNumber.": "यह फ़ील्ड मान्य क्रेडिट कार्ड नंबर नहीं है।", + "ThisFieldIsNotValid.": "यह फ़ील्ड मान्य नहीं है।", + "ThisFieldIsNotAValidEmailAddress.": "यह फ़ील्ड मान्य ई-मेल पता नहीं है।", + "ThisFieldOnlyAcceptsFilesWithTheFollowingExtensions:{0}": "यह फ़ील्ड केवल निम्नलिखित एक्सटेंशन वाली फाइलें स्वीकार करती है: {0}", + "ThisFieldMustBeAStringOrArrayTypeWithAMaximumLengthOf{0}": "यह फ़ील्ड '{0}' की अधिकतम लंबाई के साथ एक स्ट्रिंग या सरणी प्रकार होना चाहिए।", + "ThisFieldMustBeAStringOrArrayTypeWithAMinimumLengthOf{0}": "यह फ़ील्ड '{0}' की न्यूनतम लंबाई के साथ एक स्ट्रिंग या सरणी प्रकार होनी चाहिए।", + "ThisFieldIsNotAValidPhoneNumber.": "यह फ़ील्ड मान्य फ़ोन नंबर नहीं है।", + "ThisFieldMustBeBetween{0}And{1}": "यह फ़ील्ड {0} और {1} के बीच होनी चाहिए।", + "ThisFieldMustMatchTheRegularExpression{0}": "यह फ़ील्ड नियमित अभिव्यक्ति '{0}' से मेल खाना चाहिए।", + "ThisFieldIsRequired.": "यह फ़ील्ड आवश्यक है।", + "ThisFieldMustBeAStringWithAMaximumLengthOf{0}": "यह फ़ील्ड {0} की अधिकतम लंबाई के साथ एक स्ट्रिंग होनी चाहिए।", + "ThisFieldMustBeAStringWithAMinimumLengthOf{1}AndAMaximumLengthOf{0}": "यह फ़ील्ड न्यूनतम लंबाई {1} और अधिकतम लंबाई {0} के साथ होनी चाहिए।", + "ThisFieldIsNotAValidFullyQualifiedHttpHttpsOrFtpUrl": "यह फ़ील्ड एक पूरी तरह से योग्य http, https, या ftp URL नहीं है।", + "ThisFieldIsInvalid.": "यह फ़ील्ड अमान्य है।" + } +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.Validation/Volo/Abp/Validation/Localization/it.json b/framework/src/Volo.Abp.Validation/Volo/Abp/Validation/Localization/it.json new file mode 100644 index 0000000000..162e186cde --- /dev/null +++ b/framework/src/Volo.Abp.Validation/Volo/Abp/Validation/Localization/it.json @@ -0,0 +1,34 @@ +{ + "culture": "it", + "texts": { + "'{0}' and '{1}' do not match.": "\"{0}\" e \"{1}\" non corrispondono.", + "The {0} field is not a valid credit card number.": "Il campo {0} non è un numero di carta di credito valido.", + "{0} is not valid.": "{0} non è valido.", + "The {0} field is not a valid e-mail address.": "Il campo {0} non è un indirizzo e-mail valido.", + "The {0} field only accepts files with the following extensions: {1}": "Il campo {0} accetta solo file con le seguenti estensioni: {1}", + "The field {0} must be a string or array type with a maximum length of '{1}'.": "Il campo {0} deve essere una stringa o un tipo di matrice con una lunghezza massima di \"{1}\".", + "The field {0} must be a string or array type with a minimum length of '{1}'.": "Il campo {0} deve essere una stringa o un tipo di matrice con una lunghezza minima di \"{1}\".", + "The {0} field is not a valid phone number.": "Il campo {0} non è un numero di telefono valido.", + "The field {0} must be between {1} and {2}.": "Il campo {0} deve essere compreso tra {1} e {2}.", + "The field {0} must match the regular expression '{1}'.": "Il campo {0} non corrisponde al formato richiesto.", + "The {0} field is required.": "Il campo {0} è obbligatorio.", + "The field {0} must be a string with a maximum length of {1}.": "Il campo {0} deve essere una stringa con una lunghezza massima di {1}.", + "The field {0} must be a string with a minimum length of {2} and a maximum length of {1}.": "Il campo {0} deve essere una stringa con una lunghezza minima di {2} e una lunghezza massima di {1}.", + "The {0} field is not a valid fully-qualified http, https, or ftp URL.": "Il campo {0} non è un URL http, https o ftp completo e valido.", + "The field {0} is invalid.": "Il campo {0} non è valido.", + "ThisFieldIsNotAValidCreditCardNumber.": "Questo campo non è un numero di carta di credito valido.", + "ThisFieldIsNotValid.": "Questo campo non è valido.", + "ThisFieldIsNotAValidEmailAddress.": "Questo campo non è un indirizzo e-mail valido.", + "ThisFieldOnlyAcceptsFilesWithTheFollowingExtensions:{0}": "Questo campo accetta solo file con le seguenti estensioni: {0}", + "ThisFieldMustBeAStringOrArrayTypeWithAMaximumLengthOf{0}": "Questo campo deve essere un tipo stringa o matrice con una lunghezza massima di \"{0}\".", + "ThisFieldMustBeAStringOrArrayTypeWithAMinimumLengthOf{0}": "Questo campo deve essere una stringa o un tipo di matrice con una lunghezza minima di \"{0}\".", + "ThisFieldIsNotAValidPhoneNumber.": "Questo campo non è un numero di telefono valido.", + "ThisFieldMustBeBetween{0}And{1}": "Questo campo deve essere compreso tra {0} e {1}.", + "ThisFieldMustMatchTheRegularExpression{0}": "Questo campo deve corrispondere all'espressione regolare \"{0}\".", + "ThisFieldIsRequired.": "Questo campo è obbligatorio.", + "ThisFieldMustBeAStringWithAMaximumLengthOf{0}": "Questo campo deve essere una stringa con una lunghezza massima di {0}.", + "ThisFieldMustBeAStringWithAMinimumLengthOf{1}AndAMaximumLengthOf{0}": "Questo campo deve essere una stringa con una lunghezza minima di {1} e una lunghezza massima di {0}.", + "ThisFieldIsNotAValidFullyQualifiedHttpHttpsOrFtpUrl": "Questo campo non è un URL http, https o ftp completo e valido.", + "ThisFieldIsInvalid.": "Questo campo non è valido." + } +} \ No newline at end of file diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/Localization/Resource/hi.json b/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/Localization/Resource/hi.json new file mode 100644 index 0000000000..eccd8f62d7 --- /dev/null +++ b/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/Localization/Resource/hi.json @@ -0,0 +1,7 @@ +{ + "culture": "hi", + "texts": { + "BirthDate": "जन्म तिथि", + "Value1": "मान एक" + } +} \ No newline at end of file diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/Localization/Resource/it.json b/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/Localization/Resource/it.json new file mode 100644 index 0000000000..954ab19de0 --- /dev/null +++ b/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/Localization/Resource/it.json @@ -0,0 +1,7 @@ +{ + "culture": "it", + "texts": { + "BirthDate": "Data di nascita", + "Value1": "Valore uno" + } +} \ No newline at end of file diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Tests/Volo/Abp/AspNetCore/Mvc/UI/Theme/Shared/Toolbars/Toolbar_Tests.cs b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Tests/Volo/Abp/AspNetCore/Mvc/UI/Theme/Shared/Toolbars/Toolbar_Tests.cs index 70ca907fac..928a2af8de 100644 --- a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Tests/Volo/Abp/AspNetCore/Mvc/UI/Theme/Shared/Toolbars/Toolbar_Tests.cs +++ b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Tests/Volo/Abp/AspNetCore/Mvc/UI/Theme/Shared/Toolbars/Toolbar_Tests.cs @@ -11,6 +11,7 @@ using NSubstitute; using Shouldly; using Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Toolbars; using Volo.Abp.AspNetCore.Mvc.UI.Theming; +using Volo.Abp.Authorization.Permissions; using Volo.Abp.Security.Claims; using Xunit; @@ -71,8 +72,8 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Tests.Volo.Abp.AspNetCore.Mvc. return Task.CompletedTask; } - context.Toolbar.Items.Add(new ToolbarItem(typeof(MyComponent1), requiredPermissionName: "MyComponent1")); - context.Toolbar.Items.Add(new ToolbarItem(typeof(MyComponent2), requiredPermissionName: "MyComponent2")); + context.Toolbar.Items.Add(new ToolbarItem(typeof(MyComponent1)).RequirePermissions("MyComponent1")); + context.Toolbar.Items.Add(new ToolbarItem(typeof(MyComponent2)).RequirePermissions("MyComponent2")); return Task.CompletedTask; } @@ -87,7 +88,7 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Tests.Volo.Abp.AspNetCore.Mvc. return Task.CompletedTask; } - context.Toolbar.Items.Add(new ToolbarItem(typeof(MyComponent3), requiredPermissionName: "MyComponent3")); + context.Toolbar.Items.Add(new ToolbarItem(typeof(MyComponent3)).RequirePermissions("MyComponent3")); context.Toolbar.Items.Add(new ToolbarItem(typeof(MyComponent4))); return Task.CompletedTask; diff --git a/framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/PermissionStateProvider_Tests.cs b/framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/PermissionStateProvider_Tests.cs index f7ab858ac1..43dfa11330 100644 --- a/framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/PermissionStateProvider_Tests.cs +++ b/framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/PermissionStateProvider_Tests.cs @@ -5,19 +5,20 @@ using Microsoft.Extensions.DependencyInjection; using Shouldly; using Volo.Abp.Authorization.Permissions; using Volo.Abp.Security.Claims; +using Volo.Abp.SimpleStateChecking; using Xunit; namespace Volo.Abp.Authorization { public abstract class PermissionStateProvider_Tests : AuthorizationTestBase { - protected IPermissionStateManager PermissionStateManager { get; } + protected ISimpleStateCheckerManager StateCheckerManager { get; } protected IPermissionDefinitionManager PermissionDefinitionManager { get; } protected ICurrentPrincipalAccessor CurrentPrincipalAccessor { get; } public PermissionStateProvider_Tests() { - PermissionStateManager = GetRequiredService(); + StateCheckerManager = GetRequiredService>(); PermissionDefinitionManager = GetRequiredService(); CurrentPrincipalAccessor = GetRequiredService(); } @@ -29,13 +30,13 @@ namespace Volo.Abp.Authorization public async Task PermissionState_Test() { var myPermission1 = PermissionDefinitionManager.Get("MyPermission1"); - myPermission1.StateProviders.ShouldContain(x => x.GetType() == typeof(TestRequireEditionPermissionStateProvider)); + myPermission1.StateCheckers.ShouldContain(x => x.GetType() == typeof(TestRequireEditionPermissionSimpleStateChecker)); - (await PermissionStateManager.IsEnabledAsync(myPermission1)).ShouldBeFalse(); + (await StateCheckerManager.IsEnabledAsync(myPermission1)).ShouldBeFalse(); using (CurrentPrincipalAccessor.Change(new Claim(AbpClaimTypes.EditionId, Guid.NewGuid().ToString()))) { - (await PermissionStateManager.IsEnabledAsync(myPermission1)).ShouldBeTrue(); + (await StateCheckerManager.IsEnabledAsync(myPermission1)).ShouldBeTrue(); } } } @@ -44,7 +45,10 @@ namespace Volo.Abp.Authorization { protected override void AfterAddApplication(IServiceCollection services) { - services.Configure(options => options.GlobalStateProviders.Add()); + services.Configure>(options => + { + options.GlobalStateCheckers.Add(); + }); } [Fact] @@ -52,11 +56,11 @@ namespace Volo.Abp.Authorization { var myPermission2 = PermissionDefinitionManager.Get("MyPermission2"); - (await PermissionStateManager.IsEnabledAsync(myPermission2)).ShouldBeFalse(); + (await StateCheckerManager.IsEnabledAsync(myPermission2)).ShouldBeFalse(); using (CurrentPrincipalAccessor.Change(new Claim(AbpClaimTypes.Role, "admin"))) { - (await PermissionStateManager.IsEnabledAsync(myPermission2)).ShouldBeTrue(); + (await StateCheckerManager.IsEnabledAsync(myPermission2)).ShouldBeTrue(); } } } diff --git a/framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/RequirePermissionsSimpleBatchStateChecker_Tests.cs b/framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/RequirePermissionsSimpleBatchStateChecker_Tests.cs new file mode 100644 index 0000000000..a3b7a96eea --- /dev/null +++ b/framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/RequirePermissionsSimpleBatchStateChecker_Tests.cs @@ -0,0 +1,79 @@ +using System.Collections.Generic; +using System.Threading.Tasks; +using Shouldly; +using Volo.Abp.Authorization.Permissions; +using Volo.Abp.SimpleStateChecking; +using Xunit; + +namespace Volo.Abp.Authorization +{ + public class RequirePermissionsSimpleBatchStateChecker_Tests : AuthorizationTestBase + { + private readonly ISimpleStateCheckerManager _simpleStateCheckerManager; + + public RequirePermissionsSimpleBatchStateChecker_Tests() + { + _simpleStateCheckerManager = GetRequiredService>(); + } + + [Fact] + public void Switch_Current_Checker_Test() + { + var checker = RequirePermissionsSimpleBatchStateChecker.Current; + checker.ShouldNotBeNull(); + + RequirePermissionsSimpleBatchStateChecker checker2 = null; + + using (RequirePermissionsSimpleBatchStateChecker.Use(new RequirePermissionsSimpleBatchStateChecker())) + { + checker2 = RequirePermissionsSimpleBatchStateChecker.Current; + checker2.ShouldNotBeNull(); + checker2.ShouldNotBe(checker); + } + + checker2.ShouldNotBeNull(); + checker2.ShouldNotBe(checker); + } + + [Fact] + public async Task RequirePermissionsSimpleBatchStateChecker_Test() + { + var myStateEntities = new MyStateEntity[] + { + new MyStateEntity().RequirePermissions(requiresAll: true, batchCheck:true, permissions: "MyPermission3"), + new MyStateEntity().RequirePermissions(requiresAll: true, batchCheck:true, permissions: "MyPermission4"), + new MyStateEntity().RequirePermissions(requiresAll: true, batchCheck:true, permissions: "MyPermission4"), + new MyStateEntity().RequirePermissions(requiresAll: true, batchCheck:true, permissions: "MyPermission5"), + }; + + var result = await _simpleStateCheckerManager.IsEnabledAsync(myStateEntities); + + result.Count.ShouldBe(myStateEntities.Length); + + result[myStateEntities[0]].ShouldBeTrue(); + result[myStateEntities[1]].ShouldBeFalse(); + result[myStateEntities[2]].ShouldBeFalse(); + result[myStateEntities[3]].ShouldBeTrue(); + } + + class MyStateEntity : IHasSimpleStateCheckers + { + public List> StateCheckers { get; } + + public MyStateEntity() + { + StateCheckers = new List>(); + } + } + + class MyStateEntity2 : IHasSimpleStateCheckers + { + public List> StateCheckers { get; } + + public MyStateEntity2() + { + StateCheckers = new List>(); + } + } + } +} diff --git a/framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/TestGlobalRequireRolePermissionStateProvider.cs b/framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/TestGlobalRequireRolePermissionSimpleStateChecker.cs similarity index 65% rename from framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/TestGlobalRequireRolePermissionStateProvider.cs rename to framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/TestGlobalRequireRolePermissionSimpleStateChecker.cs index 6e3b58d2de..78726a343d 100644 --- a/framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/TestGlobalRequireRolePermissionStateProvider.cs +++ b/framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/TestGlobalRequireRolePermissionSimpleStateChecker.cs @@ -3,12 +3,13 @@ using Microsoft.Extensions.DependencyInjection; using Volo.Abp.Authorization.Permissions; using Volo.Abp.DependencyInjection; using Volo.Abp.Security.Claims; +using Volo.Abp.SimpleStateChecking; namespace Volo.Abp.Authorization { - public class TestGlobalRequireRolePermissionStateProvider : IPermissionStateProvider, ITransientDependency + public class TestGlobalRequireRolePermissionSimpleStateChecker : ISimpleStateChecker, ITransientDependency { - public Task IsEnabledAsync(PermissionStateContext context) + public Task IsEnabledAsync(SimpleStateCheckerContext context) { var currentPrincipalAccessor = context.ServiceProvider.GetRequiredService(); return Task.FromResult(currentPrincipalAccessor.Principal != null && currentPrincipalAccessor.Principal.IsInRole("admin")); diff --git a/framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/TestRequireEditionPermissionStateProvider.cs b/framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/TestRequireEditionPermissionSimpleStateChecker.cs similarity index 66% rename from framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/TestRequireEditionPermissionStateProvider.cs rename to framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/TestRequireEditionPermissionSimpleStateChecker.cs index a793c84431..8ce5ab9523 100644 --- a/framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/TestRequireEditionPermissionStateProvider.cs +++ b/framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/TestRequireEditionPermissionSimpleStateChecker.cs @@ -3,12 +3,13 @@ using System.Threading.Tasks; using Microsoft.Extensions.DependencyInjection; using Volo.Abp.Authorization.Permissions; using Volo.Abp.Security.Claims; +using Volo.Abp.SimpleStateChecking; namespace Volo.Abp.Authorization { - public class TestRequireEditionPermissionStateProvider : IPermissionStateProvider + public class TestRequireEditionPermissionSimpleStateChecker : ISimpleStateChecker { - public Task IsEnabledAsync(PermissionStateContext context) + public Task IsEnabledAsync(SimpleStateCheckerContext context) { var currentPrincipalAccessor = context.ServiceProvider.GetRequiredService(); return Task.FromResult(currentPrincipalAccessor.Principal?.FindEditionId() != null); diff --git a/framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/TestServices/AuthorizationTestPermissionDefinitionProvider.cs b/framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/TestServices/AuthorizationTestPermissionDefinitionProvider.cs index d67cf8febc..2f78069e96 100644 --- a/framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/TestServices/AuthorizationTestPermissionDefinitionProvider.cs +++ b/framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/TestServices/AuthorizationTestPermissionDefinitionProvider.cs @@ -17,8 +17,11 @@ namespace Volo.Abp.Authorization.TestServices group.AddPermission("MyAuthorizedService1"); - group.AddPermission("MyPermission1").AddStateProviders(new TestRequireEditionPermissionStateProvider()); + group.AddPermission("MyPermission1").StateCheckers.Add(new TestRequireEditionPermissionSimpleStateChecker()); group.AddPermission("MyPermission2"); + group.AddPermission("MyPermission3"); + group.AddPermission("MyPermission4"); + group.AddPermission("MyPermission5"); group.GetPermissionOrNull("MyAuthorizedService1").ShouldNotBeNull(); diff --git a/framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/TestServices/FakePermissionStore.cs b/framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/TestServices/FakePermissionStore.cs new file mode 100644 index 0000000000..56446bcd26 --- /dev/null +++ b/framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/TestServices/FakePermissionStore.cs @@ -0,0 +1,27 @@ +using System.Threading.Tasks; +using Volo.Abp.Authorization.Permissions; +using Volo.Abp.DependencyInjection; + +namespace Volo.Abp.Authorization.TestServices +{ + public class FakePermissionStore : IPermissionStore, ITransientDependency + { + public Task IsGrantedAsync(string name, string providerName, string providerKey) + { + return Task.FromResult(name == "MyPermission3" || name == "MyPermission5"); + } + + public Task IsGrantedAsync(string[] names, string providerName, string providerKey) + { + var result = new MultiplePermissionGrantResult(); + foreach (var name in names) + { + result.Result.Add(name, name == "MyPermission3" || name == "MyPermission5" + ? PermissionGrantResult.Granted + : PermissionGrantResult.Prohibited); + } + + return Task.FromResult(result); + } + } +} diff --git a/framework/test/Volo.Abp.Cli.Core.Tests/Volo/Abp/Cli/CommandLineArgumentParser_Tests.cs b/framework/test/Volo.Abp.Cli.Core.Tests/Volo/Abp/Cli/CommandLineArgumentParser_Tests.cs index c8d31990cf..36174f1004 100644 --- a/framework/test/Volo.Abp.Cli.Core.Tests/Volo/Abp/Cli/CommandLineArgumentParser_Tests.cs +++ b/framework/test/Volo.Abp.Cli.Core.Tests/Volo/Abp/Cli/CommandLineArgumentParser_Tests.cs @@ -64,5 +64,26 @@ namespace Volo.Abp.Cli commandLineArgs.Options.ShouldContainKey("optionC"); commandLineArgs.Options["optionC"].ShouldBe("value2"); } + + [Fact] + public void Should_Parse_From_Line_Text() + { + var commandLineArgs = _commandLineArgumentParser.Parse( + "mycommand mytarget -a value1 -b \"value with space\" --optionC" + ); + + commandLineArgs.Command.ShouldBe("mycommand"); + commandLineArgs.Target.ShouldBe("mytarget"); + commandLineArgs.Options.Any().ShouldBeTrue(); + + commandLineArgs.Options.ShouldContainKey("a"); + commandLineArgs.Options["a"].ShouldBe("value1"); + + commandLineArgs.Options.ShouldContainKey("b"); + commandLineArgs.Options["b"].ShouldBe("value with space"); + + commandLineArgs.Options.ShouldContainKey("optionC"); + commandLineArgs.Options["optionC"].ShouldBeNull(); + } } } diff --git a/framework/test/Volo.Abp.Cli.Core.Tests/Volo/Abp/Cli/ProjectNameValidation_Tests.cs b/framework/test/Volo.Abp.Cli.Core.Tests/Volo/Abp/Cli/ProjectNameValidation_Tests.cs new file mode 100644 index 0000000000..cd8581f912 --- /dev/null +++ b/framework/test/Volo.Abp.Cli.Core.Tests/Volo/Abp/Cli/ProjectNameValidation_Tests.cs @@ -0,0 +1,49 @@ +using System.IO; +using System.Threading.Tasks; +using Shouldly; +using Volo.Abp.Cli.Args; +using Volo.Abp.Cli.Commands; +using Volo.Abp.Cli.ProjectModification; +using Xunit; + +namespace Volo.Abp.Cli +{ + public class ProjectNameValidation_Tests : AbpCliTestBase + { + private readonly NewCommand _newCommand; + + public ProjectNameValidation_Tests() + { + _newCommand = GetRequiredService(); + } + + [Fact] + public async Task IllegalProjectName_Test() + { + var illegalProjectNames = new[] + { + "MyCompanyName.MyProjectName", + "MyProjectName", + "CON", //Windows doesn't accept these names as file name + "AUX", + "PRN", + "COM1", + "LPT2" + }; + + foreach (var illegalProjectName in illegalProjectNames) + { + var args = new CommandLineArgs("new", illegalProjectName); + await _newCommand.ExecuteAsync(args).ShouldThrowAsync(); + } + } + + [Fact] + public async Task ParentDirectoryContain_Test() + { + + var args = new CommandLineArgs("new", "Test..Test"); + await _newCommand.ExecuteAsync(args).ShouldThrowAsync(); + } + } +} diff --git a/framework/test/Volo.Abp.Core.Tests/Volo/Abp/AbpTestModule.cs b/framework/test/Volo.Abp.Core.Tests/Volo/Abp/AbpTestModule.cs new file mode 100644 index 0000000000..b42ff1e6e8 --- /dev/null +++ b/framework/test/Volo.Abp.Core.Tests/Volo/Abp/AbpTestModule.cs @@ -0,0 +1,9 @@ +using Volo.Abp.Modularity; + +namespace Volo.Abp +{ + public class AbpTestModule : AbpModule + { + + } +} diff --git a/framework/test/Volo.Abp.Core.Tests/Volo/Abp/SimpleStateChecking/SimpleStateCheckerTestBase.cs b/framework/test/Volo.Abp.Core.Tests/Volo/Abp/SimpleStateChecking/SimpleStateCheckerTestBase.cs new file mode 100644 index 0000000000..2debf8a66b --- /dev/null +++ b/framework/test/Volo.Abp.Core.Tests/Volo/Abp/SimpleStateChecking/SimpleStateCheckerTestBase.cs @@ -0,0 +1,105 @@ +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Threading.Tasks; +using Volo.Abp.DependencyInjection; +using Volo.Abp.Testing; + +namespace Volo.Abp.SimpleStateChecking +{ + public abstract class SimpleStateCheckerTestBase : AbpIntegratedTest + { + protected readonly ISimpleStateCheckerManager SimpleStateCheckerManager; + + public SimpleStateCheckerTestBase() + { + SimpleStateCheckerManager = GetRequiredService>(); + } + + public class MyStateEntity : IHasSimpleStateCheckers + { + public int CheckCount { get; set; } + + public int GlobalCheckCount { get; set; } + + public int MultipleCheckCount { get; set; } + + public int MultipleGlobalCheckCount { get; set; } + + public DateTime CreationTime { get; set; } + + public DateTime? LastModificationTime { get; set; } + + public List> StateCheckers { get; } + + public MyStateEntity() + { + StateCheckers = new List>(); + } + + public MyStateEntity AddSimpleStateChecker(ISimpleStateChecker checker) + { + StateCheckers.Add(checker); + return this; + } + } + + public class MySimpleStateChecker : ISimpleStateChecker + { + public Task IsEnabledAsync(SimpleStateCheckerContext context) + { + context.State.CheckCount += 1; + return Task.FromResult(context.State.CreationTime > DateTime.Parse("2020-01-01", CultureInfo.InvariantCulture)); + } + } + + public class MyGlobalSimpleStateChecker : ISimpleStateChecker, ITransientDependency + { + public Task IsEnabledAsync(SimpleStateCheckerContext context) + { + context.State.GlobalCheckCount += 1; + return Task.FromResult(context.State.LastModificationTime.HasValue); + } + } + + public class MySimpleBatchStateChecker : SimpleBatchStateCheckerBase + { + public override Task> IsEnabledAsync(SimpleBatchStateCheckerContext context) + { + foreach (var state in context.States) + { + state.MultipleCheckCount += 1; + } + + var result = new SimpleStateCheckerResult(context.States); + + foreach (var x in result) + { + result[x.Key] = x.Key.CreationTime > DateTime.Parse("2020-01-01", CultureInfo.InvariantCulture); + } + + return Task.FromResult(result); + } + } + + public class MyGlobalSimpleBatchStateChecker : SimpleBatchStateCheckerBase, ITransientDependency + { + public override Task> IsEnabledAsync(SimpleBatchStateCheckerContext context) + { + foreach (var state in context.States) + { + state.MultipleGlobalCheckCount += 1; + } + + var result = new SimpleStateCheckerResult(context.States); + + foreach (var x in result) + { + result[x.Key] = x.Key.LastModificationTime.HasValue; + } + + return Task.FromResult(result); + } + } + } +} diff --git a/framework/test/Volo.Abp.Core.Tests/Volo/Abp/SimpleStateChecking/SimpleStateChecker_CheckCount_Test.cs b/framework/test/Volo.Abp.Core.Tests/Volo/Abp/SimpleStateChecking/SimpleStateChecker_CheckCount_Test.cs new file mode 100644 index 0000000000..ff7f320bb3 --- /dev/null +++ b/framework/test/Volo.Abp.Core.Tests/Volo/Abp/SimpleStateChecking/SimpleStateChecker_CheckCount_Test.cs @@ -0,0 +1,81 @@ +using System; +using System.Globalization; +using System.Threading.Tasks; +using Shouldly; +using Xunit; + +namespace Volo.Abp.SimpleStateChecking +{ + public class SimpleStateChecker_CheckCount_Test : SimpleStateCheckerTestBase + { + [Fact] + public async Task Simple_State_Check_Should_Be_Prevent_Multiple_Checks() + { + var myStateEntities = new SimpleStateCheckerTestBase.MyStateEntity[] + { + new SimpleStateCheckerTestBase.MyStateEntity() + { + CreationTime = DateTime.Parse("2022-01-01", CultureInfo.InvariantCulture) + }, + + new SimpleStateCheckerTestBase.MyStateEntity() + { + CreationTime = DateTime.Parse("2020-01-01", CultureInfo.InvariantCulture), + } + }; + + myStateEntities[0].AddSimpleStateChecker(new MySimpleBatchStateChecker()); + myStateEntities[1].AddSimpleStateChecker(new MySimpleStateChecker()); + + (await SimpleStateCheckerManager.IsEnabledAsync(myStateEntities[0])).ShouldBeTrue(); + + myStateEntities[0].CheckCount.ShouldBe(0); + myStateEntities[0].GlobalCheckCount.ShouldBe(0); + myStateEntities[0].MultipleCheckCount.ShouldBe(1); + myStateEntities[0].MultipleGlobalCheckCount.ShouldBe(0); + + (await SimpleStateCheckerManager.IsEnabledAsync(myStateEntities[1])).ShouldBeFalse(); + + myStateEntities[1].CheckCount.ShouldBe(1); + myStateEntities[1].GlobalCheckCount.ShouldBe(0); + myStateEntities[1].MultipleCheckCount.ShouldBe(0); + myStateEntities[1].MultipleGlobalCheckCount.ShouldBe(0); + } + + [Fact] + public async Task Multiple_And_Simple_State_Check_Should_Be_Prevent_Multiple_Checks() + { + var myStateEntities = new SimpleStateCheckerTestBase.MyStateEntity[] + { + new SimpleStateCheckerTestBase.MyStateEntity() + { + CreationTime = DateTime.Parse("2022-01-01", CultureInfo.InvariantCulture) + }, + + new SimpleStateCheckerTestBase.MyStateEntity() + { + CreationTime = DateTime.Parse("2020-01-01", CultureInfo.InvariantCulture), + } + }; + + myStateEntities[0].AddSimpleStateChecker(new MySimpleBatchStateChecker()); + myStateEntities[1].AddSimpleStateChecker(new MySimpleStateChecker()); + + var result = await SimpleStateCheckerManager.IsEnabledAsync(myStateEntities); + result.Count.ShouldBe(2); + + result[myStateEntities[0]].ShouldBeTrue(); + result[myStateEntities[1]].ShouldBeFalse(); + + myStateEntities[0].CheckCount.ShouldBe(0); + myStateEntities[0].GlobalCheckCount.ShouldBe(0); + myStateEntities[0].MultipleCheckCount.ShouldBe(1); + myStateEntities[0].MultipleGlobalCheckCount.ShouldBe(0); + + myStateEntities[1].CheckCount.ShouldBe(1); + myStateEntities[1].GlobalCheckCount.ShouldBe(0); + myStateEntities[1].MultipleCheckCount.ShouldBe(0); + myStateEntities[1].MultipleGlobalCheckCount.ShouldBe(0); + } + } +} diff --git a/framework/test/Volo.Abp.Core.Tests/Volo/Abp/SimpleStateChecking/SimpleStateChecker_GlobalCheckCount_Test.cs b/framework/test/Volo.Abp.Core.Tests/Volo/Abp/SimpleStateChecking/SimpleStateChecker_GlobalCheckCount_Test.cs new file mode 100644 index 0000000000..c727238139 --- /dev/null +++ b/framework/test/Volo.Abp.Core.Tests/Volo/Abp/SimpleStateChecking/SimpleStateChecker_GlobalCheckCount_Test.cs @@ -0,0 +1,95 @@ +using System; +using System.Globalization; +using System.Threading.Tasks; +using Microsoft.Extensions.DependencyInjection; +using Shouldly; +using Xunit; + +namespace Volo.Abp.SimpleStateChecking +{ + public class SimpleStateChecker_GlobalCheckCount_Test : SimpleStateCheckerTestBase + { + protected override void AfterAddApplication(IServiceCollection services) + { + services.Configure>(options => + { + options.GlobalStateCheckers.Add(); + options.GlobalStateCheckers.Add(); + }); + + base.AfterAddApplication(services); + } + + [Fact] + public async Task Simple_State_Check_Should_Be_Prevent_Multiple_Checks() + { + var myStateEntities = new SimpleStateCheckerTestBase.MyStateEntity[] + { + new SimpleStateCheckerTestBase.MyStateEntity() + { + CreationTime = DateTime.Parse("2022-01-01", CultureInfo.InvariantCulture), + LastModificationTime = DateTime.Parse("2022-01-01", CultureInfo.InvariantCulture) + }, + + new SimpleStateCheckerTestBase.MyStateEntity() + { + CreationTime = DateTime.Parse("2020-01-01", CultureInfo.InvariantCulture) + } + }; + + myStateEntities[0].AddSimpleStateChecker(new MySimpleBatchStateChecker()); + myStateEntities[1].AddSimpleStateChecker(new MySimpleStateChecker()); + + (await SimpleStateCheckerManager.IsEnabledAsync(myStateEntities[0])).ShouldBeTrue(); + + myStateEntities[0].CheckCount.ShouldBe(0); + myStateEntities[0].GlobalCheckCount.ShouldBe(1); + myStateEntities[0].MultipleCheckCount.ShouldBe(1); + myStateEntities[0].MultipleGlobalCheckCount.ShouldBe(1); + + (await SimpleStateCheckerManager.IsEnabledAsync(myStateEntities[1])).ShouldBeFalse(); + + myStateEntities[1].CheckCount.ShouldBe(1); + myStateEntities[1].GlobalCheckCount.ShouldBe(0); + myStateEntities[1].MultipleCheckCount.ShouldBe(0); + myStateEntities[1].MultipleGlobalCheckCount.ShouldBe(0); + } + + [Fact] + public async Task Multiple_And_Simple_State_Check_Should_Be_Prevent_Multiple_Checks() + { + var myStateEntities = new SimpleStateCheckerTestBase.MyStateEntity[] + { + new SimpleStateCheckerTestBase.MyStateEntity() + { + CreationTime = DateTime.Parse("2022-01-01", CultureInfo.InvariantCulture), + LastModificationTime = DateTime.Parse("2022-01-01", CultureInfo.InvariantCulture) + }, + + new SimpleStateCheckerTestBase.MyStateEntity() + { + CreationTime = DateTime.Parse("2020-01-01", CultureInfo.InvariantCulture) + } + }; + + myStateEntities[0].AddSimpleStateChecker(new MySimpleBatchStateChecker()); + myStateEntities[1].AddSimpleStateChecker(new MySimpleStateChecker()); + + var result = await SimpleStateCheckerManager.IsEnabledAsync(myStateEntities); + result.Count.ShouldBe(2); + + result[myStateEntities[0]].ShouldBeTrue(); + result[myStateEntities[1]].ShouldBeFalse(); + + myStateEntities[0].CheckCount.ShouldBe(0); + myStateEntities[0].GlobalCheckCount.ShouldBe(1); + myStateEntities[0].MultipleCheckCount.ShouldBe(1); + myStateEntities[0].MultipleGlobalCheckCount.ShouldBe(1); + + myStateEntities[1].CheckCount.ShouldBe(0); + myStateEntities[1].GlobalCheckCount.ShouldBe(0); + myStateEntities[1].MultipleCheckCount.ShouldBe(0); + myStateEntities[1].MultipleGlobalCheckCount.ShouldBe(1); + } + } +} diff --git a/framework/test/Volo.Abp.Core.Tests/Volo/Abp/SimpleStateChecking/SimpleStateChecker_Tests.cs b/framework/test/Volo.Abp.Core.Tests/Volo/Abp/SimpleStateChecking/SimpleStateChecker_Tests.cs new file mode 100644 index 0000000000..06b7cf2eb7 --- /dev/null +++ b/framework/test/Volo.Abp.Core.Tests/Volo/Abp/SimpleStateChecking/SimpleStateChecker_Tests.cs @@ -0,0 +1,105 @@ +using System; +using System.Globalization; +using System.Threading.Tasks; +using Microsoft.Extensions.DependencyInjection; +using Shouldly; +using Xunit; + +namespace Volo.Abp.SimpleStateChecking +{ + public class SimpleStateChecker_Tests : SimpleStateCheckerTestBase + { + protected override void AfterAddApplication(IServiceCollection services) + { + services.Configure>(options => + { + options.GlobalStateCheckers.Add(); + options.GlobalStateCheckers.Add(); + }); + + base.AfterAddApplication(services); + } + + [Fact] + public async Task State_Check_Should_Be_Works() + { + var myStateEntity = new MyStateEntity() + { + CreationTime = DateTime.Parse("2021-01-01", CultureInfo.InvariantCulture), + LastModificationTime = DateTime.Parse("2021-01-01", CultureInfo.InvariantCulture) + }; + myStateEntity.AddSimpleStateChecker(new MySimpleStateChecker()); + + (await SimpleStateCheckerManager.IsEnabledAsync(myStateEntity)).ShouldBeTrue(); + + myStateEntity.CreationTime = DateTime.Parse("2001-01-01", CultureInfo.InvariantCulture); + + (await SimpleStateCheckerManager.IsEnabledAsync(myStateEntity)).ShouldBeFalse(); + } + + [Fact] + public async Task Global_State_Check_Should_Be_Works() + { + var myStateEntity = new MyStateEntity() + { + CreationTime = DateTime.Parse("2021-01-01", CultureInfo.InvariantCulture) + }; + + (await SimpleStateCheckerManager.IsEnabledAsync(myStateEntity)).ShouldBeFalse(); + + myStateEntity.LastModificationTime = DateTime.Parse("2001-01-01", CultureInfo.InvariantCulture); + + (await SimpleStateCheckerManager.IsEnabledAsync(myStateEntity)).ShouldBeTrue(); + } + + [Fact] + public async Task Multiple_State_Check_Should_Be_Works() + { + var checker = new MySimpleBatchStateChecker(); + + var myStateEntities = new MyStateEntity[] + { + new MyStateEntity() + { + CreationTime = DateTime.Parse("2021-01-01", CultureInfo.InvariantCulture), + LastModificationTime = DateTime.Parse("2021-01-01", CultureInfo.InvariantCulture) + }, + + new MyStateEntity() + { + CreationTime = DateTime.Parse("2021-01-01", CultureInfo.InvariantCulture), + LastModificationTime = DateTime.Parse("2021-01-01", CultureInfo.InvariantCulture) + } + }; + + foreach (var myStateEntity in myStateEntities) + { + myStateEntity.AddSimpleStateChecker(checker); + } + + (await SimpleStateCheckerManager.IsEnabledAsync(myStateEntities)).ShouldAllBe(x => x.Value); + + foreach (var myStateEntity in myStateEntities) + { + myStateEntity.CreationTime = DateTime.Parse("2001-01-01", CultureInfo.InvariantCulture); + } + + (await SimpleStateCheckerManager.IsEnabledAsync(myStateEntities)).ShouldAllBe(x => !x.Value); + } + + [Fact] + public async Task Multiple_Global_State_Check_Should_Be_Works() + { + var myStateEntity = new MyStateEntity() + { + CreationTime = DateTime.Parse("2021-01-01", CultureInfo.InvariantCulture) + }; + + (await SimpleStateCheckerManager.IsEnabledAsync(myStateEntity)).ShouldBeFalse(); + + myStateEntity.LastModificationTime = DateTime.Parse("2001-01-01", CultureInfo.InvariantCulture); + + (await SimpleStateCheckerManager.IsEnabledAsync(myStateEntity)).ShouldBeTrue(); + } + } +} diff --git a/framework/test/Volo.Abp.Emailing.Tests/Volo/Abp/Emailing/Localization/hi.json b/framework/test/Volo.Abp.Emailing.Tests/Volo/Abp/Emailing/Localization/hi.json new file mode 100644 index 0000000000..b9f4f11504 --- /dev/null +++ b/framework/test/Volo.Abp.Emailing.Tests/Volo/Abp/Emailing/Localization/hi.json @@ -0,0 +1,6 @@ +{ + "culture": "hi", + "texts": { + "hello": "नमस्ते" + } +} \ No newline at end of file diff --git a/framework/test/Volo.Abp.Emailing.Tests/Volo/Abp/Emailing/Localization/it.json b/framework/test/Volo.Abp.Emailing.Tests/Volo/Abp/Emailing/Localization/it.json new file mode 100644 index 0000000000..30356ca55c --- /dev/null +++ b/framework/test/Volo.Abp.Emailing.Tests/Volo/Abp/Emailing/Localization/it.json @@ -0,0 +1,6 @@ +{ + "culture": "it", + "texts": { + "hello": "Ciao" + } +} \ No newline at end of file diff --git a/framework/test/Volo.Abp.EntityFrameworkCore.Tests.SecondContext/Volo/Abp/EntityFrameworkCore/TestApp/FourthContext/FourthDbContext.cs b/framework/test/Volo.Abp.EntityFrameworkCore.Tests.SecondContext/Volo/Abp/EntityFrameworkCore/TestApp/FourthContext/FourthDbContext.cs new file mode 100644 index 0000000000..5fa8a80367 --- /dev/null +++ b/framework/test/Volo.Abp.EntityFrameworkCore.Tests.SecondContext/Volo/Abp/EntityFrameworkCore/TestApp/FourthContext/FourthDbContext.cs @@ -0,0 +1,17 @@ +using Microsoft.EntityFrameworkCore; +using Volo.Abp.EntityFrameworkCore.TestApp.ThirdDbContext; + +namespace Volo.Abp.EntityFrameworkCore.TestApp.FourthContext +{ + /* This dbcontext is just for testing to replace dbcontext from the application using ReplaceDbContextAttribute + */ + public class FourthDbContext : AbpDbContext, IFourthDbContext + { + public DbSet FourthDummyEntities { get; set; } + + public FourthDbContext(DbContextOptions options) + : base(options) + { + } + } +} diff --git a/framework/test/Volo.Abp.EntityFrameworkCore.Tests.SecondContext/Volo/Abp/EntityFrameworkCore/TestApp/FourthContext/FourthDbContextDummyEntity.cs b/framework/test/Volo.Abp.EntityFrameworkCore.Tests.SecondContext/Volo/Abp/EntityFrameworkCore/TestApp/FourthContext/FourthDbContextDummyEntity.cs new file mode 100644 index 0000000000..8043301215 --- /dev/null +++ b/framework/test/Volo.Abp.EntityFrameworkCore.Tests.SecondContext/Volo/Abp/EntityFrameworkCore/TestApp/FourthContext/FourthDbContextDummyEntity.cs @@ -0,0 +1,10 @@ +using System; +using Volo.Abp.Domain.Entities; + +namespace Volo.Abp.EntityFrameworkCore.TestApp.FourthContext +{ + public class FourthDbContextDummyEntity : AggregateRoot + { + public string Value { get; set; } + } +} diff --git a/framework/test/Volo.Abp.EntityFrameworkCore.Tests.SecondContext/Volo/Abp/EntityFrameworkCore/TestApp/FourthContext/IFourthDbContext.cs b/framework/test/Volo.Abp.EntityFrameworkCore.Tests.SecondContext/Volo/Abp/EntityFrameworkCore/TestApp/FourthContext/IFourthDbContext.cs new file mode 100644 index 0000000000..eb2380d681 --- /dev/null +++ b/framework/test/Volo.Abp.EntityFrameworkCore.Tests.SecondContext/Volo/Abp/EntityFrameworkCore/TestApp/FourthContext/IFourthDbContext.cs @@ -0,0 +1,9 @@ +using Microsoft.EntityFrameworkCore; + +namespace Volo.Abp.EntityFrameworkCore.TestApp.FourthContext +{ + public interface IFourthDbContext : IEfCoreDbContext + { + DbSet FourthDummyEntities { get; set; } + } +} diff --git a/framework/test/Volo.Abp.EntityFrameworkCore.Tests.SecondContext/Volo/Abp/EntityFrameworkCore/TestApp/SecondContext/AbpEfCoreTestSecondContextModule.cs b/framework/test/Volo.Abp.EntityFrameworkCore.Tests.SecondContext/Volo/Abp/EntityFrameworkCore/TestApp/SecondContext/AbpEfCoreTestSecondContextModule.cs index 80ece93c07..e5e02efa3b 100644 --- a/framework/test/Volo.Abp.EntityFrameworkCore.Tests.SecondContext/Volo/Abp/EntityFrameworkCore/TestApp/SecondContext/AbpEfCoreTestSecondContextModule.cs +++ b/framework/test/Volo.Abp.EntityFrameworkCore.Tests.SecondContext/Volo/Abp/EntityFrameworkCore/TestApp/SecondContext/AbpEfCoreTestSecondContextModule.cs @@ -1,4 +1,5 @@ using Microsoft.Extensions.DependencyInjection; +using Volo.Abp.EntityFrameworkCore.TestApp.FourthContext; using Volo.Abp.EntityFrameworkCore.TestApp.ThirdDbContext; using Volo.Abp.Modularity; using Volo.Abp.Threading; @@ -19,6 +20,11 @@ namespace Volo.Abp.EntityFrameworkCore.TestApp.SecondContext { options.AddDefaultRepositories(); }); + + context.Services.AddAbpDbContext(options => + { + options.AddDefaultRepositories(); + }); } public override void OnApplicationInitialization(ApplicationInitializationContext context) @@ -36,4 +42,4 @@ namespace Volo.Abp.EntityFrameworkCore.TestApp.SecondContext } } } -} \ No newline at end of file +} diff --git a/framework/test/Volo.Abp.EntityFrameworkCore.Tests/Volo/Abp/EntityFrameworkCore/AbpEntityFrameworkCoreTestModule.cs b/framework/test/Volo.Abp.EntityFrameworkCore.Tests/Volo/Abp/EntityFrameworkCore/AbpEntityFrameworkCoreTestModule.cs index a1ca2e2846..4f8faef65e 100644 --- a/framework/test/Volo.Abp.EntityFrameworkCore.Tests/Volo/Abp/EntityFrameworkCore/AbpEntityFrameworkCoreTestModule.cs +++ b/framework/test/Volo.Abp.EntityFrameworkCore.Tests/Volo/Abp/EntityFrameworkCore/AbpEntityFrameworkCoreTestModule.cs @@ -39,7 +39,7 @@ namespace Volo.Abp.EntityFrameworkCore { opt.DefaultWithDetailsFunc = q => q.Include(p => p.Phones); }); - + options.Entity(opt => { opt.DefaultWithDetailsFunc = q => q.Include(p => p.Books); @@ -76,7 +76,7 @@ namespace Volo.Abp.EntityFrameworkCore @"CREATE VIEW View_PersonView AS SELECT Name, CreationTime, Birthday, LastActive FROM People"); } - + return connection; } } diff --git a/framework/test/Volo.Abp.EntityFrameworkCore.Tests/Volo/Abp/EntityFrameworkCore/DbContext_Replace_Tests.cs b/framework/test/Volo.Abp.EntityFrameworkCore.Tests/Volo/Abp/EntityFrameworkCore/DbContext_Replace_Tests.cs index 8fd88f23fe..4e343e7331 100644 --- a/framework/test/Volo.Abp.EntityFrameworkCore.Tests/Volo/Abp/EntityFrameworkCore/DbContext_Replace_Tests.cs +++ b/framework/test/Volo.Abp.EntityFrameworkCore.Tests/Volo/Abp/EntityFrameworkCore/DbContext_Replace_Tests.cs @@ -4,6 +4,7 @@ using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Options; using Shouldly; using Volo.Abp.Domain.Repositories; +using Volo.Abp.EntityFrameworkCore.TestApp.FourthContext; using Volo.Abp.EntityFrameworkCore.TestApp.ThirdDbContext; using Volo.Abp.TestApp.Domain; using Volo.Abp.TestApp.EntityFrameworkCore; @@ -15,13 +16,15 @@ namespace Volo.Abp.EntityFrameworkCore public class DbContext_Replace_Tests : EntityFrameworkCoreTestBase { private readonly IBasicRepository _dummyRepository; - private readonly IPersonRepository _personRepository; + private readonly IBasicRepository _fourthDummyRepository; + private readonly IPersonRepository _personRepository; private readonly IUnitOfWorkManager _unitOfWorkManager; private readonly AbpDbContextOptions _options; public DbContext_Replace_Tests() { _dummyRepository = GetRequiredService>(); + _fourthDummyRepository = GetRequiredService>(); _personRepository = GetRequiredService(); _unitOfWorkManager = GetRequiredService(); _options = GetRequiredService>().Value; @@ -31,8 +34,10 @@ namespace Volo.Abp.EntityFrameworkCore public async Task Should_Replace_DbContext() { _options.GetReplacedTypeOrSelf(typeof(IThirdDbContext)).ShouldBe(typeof(TestAppDbContext)); - + _options.GetReplacedTypeOrSelf(typeof(IFourthDbContext)).ShouldBe(typeof(TestAppDbContext)); + (ServiceProvider.GetRequiredService() is TestAppDbContext).ShouldBeTrue(); + (ServiceProvider.GetRequiredService() is TestAppDbContext).ShouldBeTrue(); using (var uow = _unitOfWorkManager.Begin()) { @@ -44,11 +49,19 @@ namespace Volo.Abp.EntityFrameworkCore var instance3 = await _personRepository.GetDbContextAsync(); (instance3 is TestAppDbContext).ShouldBeTrue(); - + + var instance4 = await _fourthDummyRepository.GetDbContextAsync(); + (instance4 is IFourthDbContext).ShouldBeTrue(); + + var instance5 = await _fourthDummyRepository.GetDbContextAsync(); + (instance5 is TestAppDbContext).ShouldBeTrue(); + // All instances should be the same! instance3.ShouldBe(instance1); instance3.ShouldBe(instance2); - + instance3.ShouldBe(instance4); + instance3.ShouldBe(instance5); + await uow.CompleteAsync(); } } diff --git a/framework/test/Volo.Abp.EntityFrameworkCore.Tests/Volo/Abp/TestApp/EntityFrameworkCore/TestAppDbContext.cs b/framework/test/Volo.Abp.EntityFrameworkCore.Tests/Volo/Abp/TestApp/EntityFrameworkCore/TestAppDbContext.cs index 2b4e5ec66c..82f7bf289c 100644 --- a/framework/test/Volo.Abp.EntityFrameworkCore.Tests/Volo/Abp/TestApp/EntityFrameworkCore/TestAppDbContext.cs +++ b/framework/test/Volo.Abp.EntityFrameworkCore.Tests/Volo/Abp/TestApp/EntityFrameworkCore/TestAppDbContext.cs @@ -1,13 +1,18 @@ using Microsoft.EntityFrameworkCore; +using Volo.Abp.DependencyInjection; using Volo.Abp.EntityFrameworkCore; using Volo.Abp.EntityFrameworkCore.Modeling; +using Volo.Abp.EntityFrameworkCore.TestApp.FourthContext; using Volo.Abp.EntityFrameworkCore.TestApp.ThirdDbContext; using Volo.Abp.TestApp.Domain; namespace Volo.Abp.TestApp.EntityFrameworkCore { - public class TestAppDbContext : AbpDbContext, IThirdDbContext + [ReplaceDbContext(typeof(IFourthDbContext))] + public class TestAppDbContext : AbpDbContext, IThirdDbContext, IFourthDbContext { + private DbSet _dummyEntities; + private DbSet _dummyEntities1; public DbSet People { get; set; } public DbSet Cities { get; set; } @@ -20,6 +25,8 @@ namespace Volo.Abp.TestApp.EntityFrameworkCore public DbSet Author { get; set; } + public DbSet FourthDummyEntities { get; set; } + public TestAppDbContext(DbContextOptions options) : base(options) { diff --git a/framework/test/Volo.Abp.Http.Client.Tests/Volo/Abp/Http/DynamicProxying/RegularTestControllerClientProxy_Tests.cs b/framework/test/Volo.Abp.Http.Client.Tests/Volo/Abp/Http/DynamicProxying/RegularTestControllerClientProxy_Tests.cs index 2ac327e5e7..bd35016989 100644 --- a/framework/test/Volo.Abp.Http.Client.Tests/Volo/Abp/Http/DynamicProxying/RegularTestControllerClientProxy_Tests.cs +++ b/framework/test/Volo.Abp.Http.Client.Tests/Volo/Abp/Http/DynamicProxying/RegularTestControllerClientProxy_Tests.cs @@ -46,7 +46,7 @@ namespace Volo.Abp.Http.DynamicProxying { var dateTime1 = new DateTime(2020, 04, 19, 19, 05, 01); var result = await _controller.GetWithDateTimeParameterAsync(dateTime1); - result.ShouldBe(dateTime1); + result.ToUniversalTime().ShouldBe(dateTime1.ToUniversalTime()); } [Fact] @@ -56,7 +56,7 @@ namespace Volo.Abp.Http.DynamicProxying { var dateTime1 = new DateTime(2020, 04, 19, 19, 05, 01); var result = await _controller.GetWithDateTimeParameterAsync(dateTime1); - result.ShouldBe(dateTime1); + result.ToUniversalTime().ShouldBe(dateTime1.ToUniversalTime()); } } diff --git a/framework/test/Volo.Abp.Http.Client.Tests/Volo/Abp/Http/Localization/FR.json b/framework/test/Volo.Abp.Http.Client.Tests/Volo/Abp/Http/Localization/FR.json deleted file mode 100644 index b4da8701fe..0000000000 --- a/framework/test/Volo.Abp.Http.Client.Tests/Volo/Abp/Http/Localization/FR.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "culture": "fr", - "texts": { - "Volo.Abp.Http.DynamicProxying:10001": "Exception commerciale avec données: {0}" - } -} \ No newline at end of file diff --git a/framework/test/Volo.Abp.Http.Client.Tests/Volo/Abp/Http/Localization/fr.json b/framework/test/Volo.Abp.Http.Client.Tests/Volo/Abp/Http/Localization/fr.json new file mode 100644 index 0000000000..6690705ba2 --- /dev/null +++ b/framework/test/Volo.Abp.Http.Client.Tests/Volo/Abp/Http/Localization/fr.json @@ -0,0 +1,6 @@ +{ + "culture": "fr", + "texts": { + "Volo.Abp.Http.DynamicProxying:10001": "Exception métier avec données: {0}" + } +} \ No newline at end of file diff --git a/framework/test/Volo.Abp.Http.Client.Tests/Volo/Abp/Http/Localization/hi.json b/framework/test/Volo.Abp.Http.Client.Tests/Volo/Abp/Http/Localization/hi.json new file mode 100644 index 0000000000..8e10f1518b --- /dev/null +++ b/framework/test/Volo.Abp.Http.Client.Tests/Volo/Abp/Http/Localization/hi.json @@ -0,0 +1,6 @@ +{ + "culture": "hi", + "texts": { + "Volo.Abp.Http.DynamicProxying:10001": "डेटा के साथ व्यावसायिक अपवाद: {0}" + } +} \ No newline at end of file diff --git a/framework/test/Volo.Abp.Http.Client.Tests/Volo/Abp/Http/Localization/it.json b/framework/test/Volo.Abp.Http.Client.Tests/Volo/Abp/Http/Localization/it.json new file mode 100644 index 0000000000..4920b4a0e4 --- /dev/null +++ b/framework/test/Volo.Abp.Http.Client.Tests/Volo/Abp/Http/Localization/it.json @@ -0,0 +1,6 @@ +{ + "culture": "it", + "texts": { + "Volo.Abp.Http.DynamicProxying:10001": "Eccezione aziendale con dati: {0}" + } +} \ No newline at end of file diff --git a/framework/test/Volo.Abp.Localization.Tests/Volo/Abp/Localization/TestResources/Base/CountryNames/hi.json b/framework/test/Volo.Abp.Localization.Tests/Volo/Abp/Localization/TestResources/Base/CountryNames/hi.json new file mode 100644 index 0000000000..9917b1efd5 --- /dev/null +++ b/framework/test/Volo.Abp.Localization.Tests/Volo/Abp/Localization/TestResources/Base/CountryNames/hi.json @@ -0,0 +1,7 @@ +{ + "culture": "hi", + "texts": { + "USA": "संयुक्त राज्य अमेरिका", + "Brazil": "ब्राज़िल" + } +} \ No newline at end of file diff --git a/framework/test/Volo.Abp.Localization.Tests/Volo/Abp/Localization/TestResources/Base/CountryNames/it.json b/framework/test/Volo.Abp.Localization.Tests/Volo/Abp/Localization/TestResources/Base/CountryNames/it.json new file mode 100644 index 0000000000..965756dd99 --- /dev/null +++ b/framework/test/Volo.Abp.Localization.Tests/Volo/Abp/Localization/TestResources/Base/CountryNames/it.json @@ -0,0 +1,7 @@ +{ + "culture": "it", + "texts": { + "USA": "Stati Uniti d'America", + "Brazil": "Brasile" + } +} \ No newline at end of file diff --git a/framework/test/Volo.Abp.Localization.Tests/Volo/Abp/Localization/TestResources/Base/Validation/hi.json b/framework/test/Volo.Abp.Localization.Tests/Volo/Abp/Localization/TestResources/Base/Validation/hi.json new file mode 100644 index 0000000000..a1e297d853 --- /dev/null +++ b/framework/test/Volo.Abp.Localization.Tests/Volo/Abp/Localization/TestResources/Base/Validation/hi.json @@ -0,0 +1,7 @@ +{ + "culture": "hi", + "texts": { + "ThisFieldIsRequired": "यह फ़ील्ड आवश्यक है", + "MaxLenghtErrorMessage": "यह क्षेत्र अधिकतम '{0}' वर्ण का हो सकता है" + } +} \ No newline at end of file diff --git a/framework/test/Volo.Abp.Localization.Tests/Volo/Abp/Localization/TestResources/Base/Validation/it.json b/framework/test/Volo.Abp.Localization.Tests/Volo/Abp/Localization/TestResources/Base/Validation/it.json new file mode 100644 index 0000000000..1279ed4fe7 --- /dev/null +++ b/framework/test/Volo.Abp.Localization.Tests/Volo/Abp/Localization/TestResources/Base/Validation/it.json @@ -0,0 +1,7 @@ +{ + "culture": "it", + "texts": { + "ThisFieldIsRequired": "Questo campo è obbligatorio", + "MaxLenghtErrorMessage": "Questo campo può contenere un massimo di caratteri \"{0}\"" + } +} \ No newline at end of file diff --git a/framework/test/Volo.Abp.Localization.Tests/Volo/Abp/Localization/TestResources/Source/hi.json b/framework/test/Volo.Abp.Localization.Tests/Volo/Abp/Localization/TestResources/Source/hi.json new file mode 100644 index 0000000000..22573158a4 --- /dev/null +++ b/framework/test/Volo.Abp.Localization.Tests/Volo/Abp/Localization/TestResources/Source/hi.json @@ -0,0 +1,11 @@ +{ + "culture": "hi", + "texts": { + "Hello {0}.": "नमस्ते {0} ।", + "Car": "गाड़ी", + "CarPlural": "कारों", + "MaxLenghtErrorMessage": "इस क्षेत्र की लंबाई अधिकतम '{0}' वर्ण हो सकती है", + "Universe": "ब्रम्हांड", + "FortyTwo": "बयालीस" + } +} \ No newline at end of file diff --git a/framework/test/Volo.Abp.Localization.Tests/Volo/Abp/Localization/TestResources/Source/it.json b/framework/test/Volo.Abp.Localization.Tests/Volo/Abp/Localization/TestResources/Source/it.json new file mode 100644 index 0000000000..677afdd19e --- /dev/null +++ b/framework/test/Volo.Abp.Localization.Tests/Volo/Abp/Localization/TestResources/Source/it.json @@ -0,0 +1,11 @@ +{ + "culture": "it", + "texts": { + "Hello {0}.": "Salve {0} .", + "Car": "Auto", + "CarPlural": "Automobili", + "MaxLenghtErrorMessage": "La lunghezza di questo campo può essere al massimo di caratteri \"{0}\"", + "Universe": "Universo", + "FortyTwo": "Quarantadue" + } +} \ No newline at end of file diff --git a/framework/test/Volo.Abp.Localization.Tests/Volo/Abp/Localization/TestResources/SourceExt/hi.json b/framework/test/Volo.Abp.Localization.Tests/Volo/Abp/Localization/TestResources/SourceExt/hi.json new file mode 100644 index 0000000000..b05c0205f4 --- /dev/null +++ b/framework/test/Volo.Abp.Localization.Tests/Volo/Abp/Localization/TestResources/SourceExt/hi.json @@ -0,0 +1,6 @@ +{ + "culture": "hi", + "texts": { + "SeeYou": "फिर मिलते हैं" + } +} \ No newline at end of file diff --git a/framework/test/Volo.Abp.MongoDB.Tests.SecondContext/Volo.Abp.MongoDB.Tests.SecondContext.csproj b/framework/test/Volo.Abp.MongoDB.Tests.SecondContext/Volo.Abp.MongoDB.Tests.SecondContext.csproj new file mode 100644 index 0000000000..e779329ad7 --- /dev/null +++ b/framework/test/Volo.Abp.MongoDB.Tests.SecondContext/Volo.Abp.MongoDB.Tests.SecondContext.csproj @@ -0,0 +1,19 @@ + + + + + + net5.0 + $(AssetTargetFallback);portable-net45+win8+wp8+wpa81; + true + true + true + true + + + + + + + + diff --git a/framework/test/Volo.Abp.MongoDB.Tests.SecondContext/Volo/Abp/MongoDB/TestApp/FourthContext/FourthDbContext.cs b/framework/test/Volo.Abp.MongoDB.Tests.SecondContext/Volo/Abp/MongoDB/TestApp/FourthContext/FourthDbContext.cs new file mode 100644 index 0000000000..7b496f954f --- /dev/null +++ b/framework/test/Volo.Abp.MongoDB.Tests.SecondContext/Volo/Abp/MongoDB/TestApp/FourthContext/FourthDbContext.cs @@ -0,0 +1,13 @@ +using MongoDB.Driver; +using Volo.Abp.EntityFrameworkCore.TestApp.FourthContext; + +namespace Volo.Abp.MongoDB.TestApp.FourthContext +{ + /* This dbcontext is just for testing to replace dbcontext from the application using ReplaceDbContextAttribute + */ + public class FourthDbContext : AbpMongoDbContext, IFourthDbContext + { + public IMongoCollection FourthDummyEntities => Collection(); + + } +} diff --git a/framework/test/Volo.Abp.MongoDB.Tests.SecondContext/Volo/Abp/MongoDB/TestApp/FourthContext/FourthDbContextDummyEntity.cs b/framework/test/Volo.Abp.MongoDB.Tests.SecondContext/Volo/Abp/MongoDB/TestApp/FourthContext/FourthDbContextDummyEntity.cs new file mode 100644 index 0000000000..8043301215 --- /dev/null +++ b/framework/test/Volo.Abp.MongoDB.Tests.SecondContext/Volo/Abp/MongoDB/TestApp/FourthContext/FourthDbContextDummyEntity.cs @@ -0,0 +1,10 @@ +using System; +using Volo.Abp.Domain.Entities; + +namespace Volo.Abp.EntityFrameworkCore.TestApp.FourthContext +{ + public class FourthDbContextDummyEntity : AggregateRoot + { + public string Value { get; set; } + } +} diff --git a/framework/test/Volo.Abp.MongoDB.Tests.SecondContext/Volo/Abp/MongoDB/TestApp/FourthContext/IFourthDbContext.cs b/framework/test/Volo.Abp.MongoDB.Tests.SecondContext/Volo/Abp/MongoDB/TestApp/FourthContext/IFourthDbContext.cs new file mode 100644 index 0000000000..ae9ee2f281 --- /dev/null +++ b/framework/test/Volo.Abp.MongoDB.Tests.SecondContext/Volo/Abp/MongoDB/TestApp/FourthContext/IFourthDbContext.cs @@ -0,0 +1,10 @@ +using MongoDB.Driver; +using Volo.Abp.EntityFrameworkCore.TestApp.FourthContext; + +namespace Volo.Abp.MongoDB.TestApp.FourthContext +{ + public interface IFourthDbContext : IAbpMongoDbContext + { + IMongoCollection FourthDummyEntities { get;} + } +} diff --git a/framework/test/Volo.Abp.MongoDB.Tests.SecondContext/Volo/Abp/MongoDB/TestApp/SecondContext/AbpMongoDbTestSecondContextModule.cs b/framework/test/Volo.Abp.MongoDB.Tests.SecondContext/Volo/Abp/MongoDB/TestApp/SecondContext/AbpMongoDbTestSecondContextModule.cs new file mode 100644 index 0000000000..ba5eaf7f79 --- /dev/null +++ b/framework/test/Volo.Abp.MongoDB.Tests.SecondContext/Volo/Abp/MongoDB/TestApp/SecondContext/AbpMongoDbTestSecondContextModule.cs @@ -0,0 +1,45 @@ +using Microsoft.Extensions.DependencyInjection; +using Volo.Abp.Modularity; +using Volo.Abp.MongoDB.TestApp.FourthContext; +using Volo.Abp.MongoDB.TestApp.ThirdDbContext; +using Volo.Abp.Threading; + +namespace Volo.Abp.MongoDB.TestApp.SecondContext +{ + [DependsOn(typeof(AbpMongoDbModule))] + public class AbpMongoDbTestSecondContextModule : AbpModule + { + public override void ConfigureServices(ServiceConfigurationContext context) + { + context.Services.AddMongoDbContext(options => + { + options.AddDefaultRepositories(); + }); + + context.Services.AddMongoDbContext(options => + { + options.AddDefaultRepositories(); + }); + + context.Services.AddMongoDbContext(options => + { + options.AddDefaultRepositories(); + }); + } + + public override void OnApplicationInitialization(ApplicationInitializationContext context) + { + SeedTestData(context); + } + + private static void SeedTestData(ApplicationInitializationContext context) + { + using (var scope = context.ServiceProvider.CreateScope()) + { + AsyncHelper.RunSync(() => scope.ServiceProvider + .GetRequiredService() + .BuildAsync()); + } + } + } +} diff --git a/framework/test/Volo.Abp.MongoDB.Tests.SecondContext/Volo/Abp/MongoDB/TestApp/SecondContext/BookInSecondDbContext.cs b/framework/test/Volo.Abp.MongoDB.Tests.SecondContext/Volo/Abp/MongoDB/TestApp/SecondContext/BookInSecondDbContext.cs new file mode 100644 index 0000000000..d7e81f4258 --- /dev/null +++ b/framework/test/Volo.Abp.MongoDB.Tests.SecondContext/Volo/Abp/MongoDB/TestApp/SecondContext/BookInSecondDbContext.cs @@ -0,0 +1,21 @@ +using System; +using Volo.Abp.Domain.Entities; + +namespace Volo.Abp.MongoDB.TestApp.SecondContext +{ + public class BookInSecondDbContext : AggregateRoot + { + public string Name { get; set; } + + public BookInSecondDbContext() + { + + } + + public BookInSecondDbContext(Guid id, string name) + : base(id) + { + Name = name; + } + } +} diff --git a/framework/test/Volo.Abp.MongoDB.Tests.SecondContext/Volo/Abp/MongoDB/TestApp/SecondContext/PhoneInSecondDbContext.cs b/framework/test/Volo.Abp.MongoDB.Tests.SecondContext/Volo/Abp/MongoDB/TestApp/SecondContext/PhoneInSecondDbContext.cs new file mode 100644 index 0000000000..d808d5a52a --- /dev/null +++ b/framework/test/Volo.Abp.MongoDB.Tests.SecondContext/Volo/Abp/MongoDB/TestApp/SecondContext/PhoneInSecondDbContext.cs @@ -0,0 +1,18 @@ +using System; +using System.ComponentModel.DataAnnotations.Schema; +using Volo.Abp.Domain.Entities; + +namespace Volo.Abp.MongoDB.TestApp.SecondContext +{ + public class PhoneInSecondDbContext : AggregateRoot + { + public virtual Guid PersonId { get; set; } + + public virtual string Number { get; set; } + + public override object[] GetKeys() + { + return new object[] {PersonId, Number}; + } + } +} diff --git a/framework/test/Volo.Abp.MongoDB.Tests.SecondContext/Volo/Abp/MongoDB/TestApp/SecondContext/SecondContextTestDataBuilder.cs b/framework/test/Volo.Abp.MongoDB.Tests.SecondContext/Volo/Abp/MongoDB/TestApp/SecondContext/SecondContextTestDataBuilder.cs new file mode 100644 index 0000000000..c3fb902c64 --- /dev/null +++ b/framework/test/Volo.Abp.MongoDB.Tests.SecondContext/Volo/Abp/MongoDB/TestApp/SecondContext/SecondContextTestDataBuilder.cs @@ -0,0 +1,30 @@ +using System; +using System.Threading.Tasks; +using Volo.Abp.DependencyInjection; +using Volo.Abp.Domain.Repositories; +using Volo.Abp.Guids; + +namespace Volo.Abp.MongoDB.TestApp.SecondContext +{ + public class SecondContextTestDataBuilder : ITransientDependency + { + private readonly IBasicRepository _bookRepository; + private readonly IGuidGenerator _guidGenerator; + + public SecondContextTestDataBuilder(IBasicRepository bookRepository, IGuidGenerator guidGenerator) + { + _bookRepository = bookRepository; + _guidGenerator = guidGenerator; + } + + public async Task BuildAsync() + { + await _bookRepository.InsertAsync( + new BookInSecondDbContext( + _guidGenerator.Create(), + "TestBook1" + ) + ); + } + } +} diff --git a/framework/test/Volo.Abp.MongoDB.Tests.SecondContext/Volo/Abp/MongoDB/TestApp/SecondContext/SecondDbContext.cs b/framework/test/Volo.Abp.MongoDB.Tests.SecondContext/Volo/Abp/MongoDB/TestApp/SecondContext/SecondDbContext.cs new file mode 100644 index 0000000000..2df5785b20 --- /dev/null +++ b/framework/test/Volo.Abp.MongoDB.Tests.SecondContext/Volo/Abp/MongoDB/TestApp/SecondContext/SecondDbContext.cs @@ -0,0 +1,11 @@ +using MongoDB.Driver; + +namespace Volo.Abp.MongoDB.TestApp.SecondContext +{ + public class SecondDbContext : AbpMongoDbContext + { + public IMongoCollection Books => Collection(); + + public IMongoCollection Phones => Collection(); + } +} diff --git a/framework/test/Volo.Abp.MongoDB.Tests.SecondContext/Volo/Abp/MongoDB/TestApp/ThirdDbContext/IThirdDbContext.cs b/framework/test/Volo.Abp.MongoDB.Tests.SecondContext/Volo/Abp/MongoDB/TestApp/ThirdDbContext/IThirdDbContext.cs new file mode 100644 index 0000000000..cfe629b5a7 --- /dev/null +++ b/framework/test/Volo.Abp.MongoDB.Tests.SecondContext/Volo/Abp/MongoDB/TestApp/ThirdDbContext/IThirdDbContext.cs @@ -0,0 +1,9 @@ +using MongoDB.Driver; + +namespace Volo.Abp.MongoDB.TestApp.ThirdDbContext +{ + public interface IThirdDbContext : IAbpMongoDbContext + { + IMongoCollection DummyEntities { get; } + } +} diff --git a/framework/test/Volo.Abp.MongoDB.Tests.SecondContext/Volo/Abp/MongoDB/TestApp/ThirdDbContext/ThirdDbContext.cs b/framework/test/Volo.Abp.MongoDB.Tests.SecondContext/Volo/Abp/MongoDB/TestApp/ThirdDbContext/ThirdDbContext.cs new file mode 100644 index 0000000000..c3b018a699 --- /dev/null +++ b/framework/test/Volo.Abp.MongoDB.Tests.SecondContext/Volo/Abp/MongoDB/TestApp/ThirdDbContext/ThirdDbContext.cs @@ -0,0 +1,11 @@ +using MongoDB.Driver; + +namespace Volo.Abp.MongoDB.TestApp.ThirdDbContext +{ + /* This dbcontext is just for testing to replace dbcontext from the application using AbpDbContextRegistrationOptions.ReplaceDbContext + */ + public class ThirdDbContext : AbpMongoDbContext, IThirdDbContext + { + public IMongoCollection DummyEntities => Collection(); + } +} diff --git a/framework/test/Volo.Abp.MongoDB.Tests.SecondContext/Volo/Abp/MongoDB/TestApp/ThirdDbContext/ThirdDbContextDummyEntity.cs b/framework/test/Volo.Abp.MongoDB.Tests.SecondContext/Volo/Abp/MongoDB/TestApp/ThirdDbContext/ThirdDbContextDummyEntity.cs new file mode 100644 index 0000000000..a784406ff5 --- /dev/null +++ b/framework/test/Volo.Abp.MongoDB.Tests.SecondContext/Volo/Abp/MongoDB/TestApp/ThirdDbContext/ThirdDbContextDummyEntity.cs @@ -0,0 +1,10 @@ +using System; +using Volo.Abp.Domain.Entities; + +namespace Volo.Abp.MongoDB.TestApp.ThirdDbContext +{ + public class ThirdDbContextDummyEntity : AggregateRoot + { + public string Value { get; set; } + } +} diff --git a/framework/test/Volo.Abp.MongoDB.Tests/Volo.Abp.MongoDB.Tests.csproj b/framework/test/Volo.Abp.MongoDB.Tests/Volo.Abp.MongoDB.Tests.csproj index c36fbb799c..21bcac616e 100644 --- a/framework/test/Volo.Abp.MongoDB.Tests/Volo.Abp.MongoDB.Tests.csproj +++ b/framework/test/Volo.Abp.MongoDB.Tests/Volo.Abp.MongoDB.Tests.csproj @@ -9,8 +9,8 @@ - + diff --git a/framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/MongoDB/AbpMongoDbTestModule.cs b/framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/MongoDB/AbpMongoDbTestModule.cs index e580c6fce6..100011560e 100644 --- a/framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/MongoDB/AbpMongoDbTestModule.cs +++ b/framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/MongoDB/AbpMongoDbTestModule.cs @@ -1,21 +1,18 @@ using System; -using System.Linq; -using System.Threading; using Microsoft.Extensions.DependencyInjection; -using MongoDB.Driver; -using MongoDB.Driver.Core.Servers; using Volo.Abp.Data; using Volo.Abp.Modularity; +using Volo.Abp.MongoDB.TestApp.SecondContext; +using Volo.Abp.MongoDB.TestApp.ThirdDbContext; using Volo.Abp.TestApp; using Volo.Abp.TestApp.Domain; using Volo.Abp.TestApp.MongoDB; -using Volo.Abp.Uow; namespace Volo.Abp.MongoDB { [DependsOn( - typeof(AbpMongoDbModule), - typeof(TestAppModule) + typeof(TestAppModule), + typeof(AbpMongoDbTestSecondContextModule) )] public class AbpMongoDbTestModule : AbpModule { @@ -35,6 +32,8 @@ namespace Volo.Abp.MongoDB { options.AddDefaultRepositories(); options.AddRepository(); + + options.ReplaceDbContext(); }); } } diff --git a/framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/MongoDB/DbContext_Replace_Tests.cs b/framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/MongoDB/DbContext_Replace_Tests.cs new file mode 100644 index 0000000000..eefa6852bf --- /dev/null +++ b/framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/MongoDB/DbContext_Replace_Tests.cs @@ -0,0 +1,31 @@ +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Options; +using Shouldly; +using Volo.Abp.MongoDB.TestApp.FourthContext; +using Volo.Abp.MongoDB.TestApp.ThirdDbContext; +using Volo.Abp.TestApp.MongoDB; +using Xunit; + +namespace Volo.Abp.MongoDB +{ + [Collection(MongoTestCollection.Name)] + public class DbContext_Replace_Tests : MongoDbTestBase + { + private readonly AbpMongoDbContextOptions _options; + + public DbContext_Replace_Tests() + { + _options = GetRequiredService>().Value; + } + + [Fact] + public void Should_Replace_DbContext() + { + _options.GetReplacedTypeOrSelf(typeof(IThirdDbContext)).ShouldBe(typeof(TestAppMongoDbContext)); + _options.GetReplacedTypeOrSelf(typeof(IFourthDbContext)).ShouldBe(typeof(TestAppMongoDbContext)); + + (ServiceProvider.GetRequiredService() is TestAppMongoDbContext).ShouldBeTrue(); + (ServiceProvider.GetRequiredService() is TestAppMongoDbContext).ShouldBeTrue(); + } + } +} diff --git a/framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/TestApp/MongoDb/TestAppMongoDbContext.cs b/framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/TestApp/MongoDb/TestAppMongoDbContext.cs index eed8d4ade3..68a2856e01 100644 --- a/framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/TestApp/MongoDb/TestAppMongoDbContext.cs +++ b/framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/TestApp/MongoDb/TestAppMongoDbContext.cs @@ -1,12 +1,17 @@ using MongoDB.Driver; using Volo.Abp.Data; +using Volo.Abp.DependencyInjection; +using Volo.Abp.EntityFrameworkCore.TestApp.FourthContext; using Volo.Abp.MongoDB; +using Volo.Abp.MongoDB.TestApp.FourthContext; +using Volo.Abp.MongoDB.TestApp.ThirdDbContext; using Volo.Abp.TestApp.Domain; namespace Volo.Abp.TestApp.MongoDB { [ConnectionStringName("TestApp")] - public class TestAppMongoDbContext : AbpMongoDbContext, ITestAppMongoDbContext + [ReplaceDbContext(typeof(IFourthDbContext))] + public class TestAppMongoDbContext : AbpMongoDbContext, ITestAppMongoDbContext, IThirdDbContext, IFourthDbContext { [MongoCollection("Persons")] //Intentionally changed the collection name to test it public IMongoCollection People => Collection(); @@ -15,6 +20,10 @@ namespace Volo.Abp.TestApp.MongoDB public IMongoCollection Cities => Collection(); + public IMongoCollection DummyEntities => Collection(); + + public IMongoCollection FourthDummyEntities => Collection(); + protected internal override void CreateModel(IMongoModelBuilder modelBuilder) { base.CreateModel(modelBuilder); diff --git a/framework/test/Volo.Abp.TextTemplating.Tests/Volo/Abp/TextTemplating/Localization/hi.json b/framework/test/Volo.Abp.TextTemplating.Tests/Volo/Abp/TextTemplating/Localization/hi.json new file mode 100644 index 0000000000..1f5eb39e16 --- /dev/null +++ b/framework/test/Volo.Abp.TextTemplating.Tests/Volo/Abp/TextTemplating/Localization/hi.json @@ -0,0 +1,7 @@ +{ + "culture": "hi", + "texts": { + "HelloText": "नमस्ते {0}", + "HowAreYou": "क्या हाल है?" + } +} \ No newline at end of file diff --git a/framework/test/Volo.Abp.TextTemplating.Tests/Volo/Abp/TextTemplating/Localization/it.json b/framework/test/Volo.Abp.TextTemplating.Tests/Volo/Abp/TextTemplating/Localization/it.json new file mode 100644 index 0000000000..1081d7b301 --- /dev/null +++ b/framework/test/Volo.Abp.TextTemplating.Tests/Volo/Abp/TextTemplating/Localization/it.json @@ -0,0 +1,7 @@ +{ + "culture": "it", + "texts": { + "HelloText": "Salve {0}", + "HowAreYou": "come va?" + } +} \ No newline at end of file diff --git a/framework/test/Volo.Abp.UI.Navigation.Tests/Volo/Abp/Ui/Navigation/MenuManager_Tests.cs b/framework/test/Volo.Abp.UI.Navigation.Tests/Volo/Abp/Ui/Navigation/MenuManager_Tests.cs index c72082945b..d641969f9a 100644 --- a/framework/test/Volo.Abp.UI.Navigation.Tests/Volo/Abp/Ui/Navigation/MenuManager_Tests.cs +++ b/framework/test/Volo.Abp.UI.Navigation.Tests/Volo/Abp/Ui/Navigation/MenuManager_Tests.cs @@ -5,6 +5,7 @@ using System.Threading.Tasks; using Microsoft.Extensions.DependencyInjection; using NSubstitute; using Shouldly; +using Volo.Abp.Authorization.Permissions; using Volo.Abp.Security.Claims; using Volo.Abp.Testing; using Xunit; @@ -73,8 +74,8 @@ namespace Volo.Abp.UI.Navigation var administration = context.Menu.GetAdministration(); - administration.AddItem(new ApplicationMenuItem("Administration.UserManagement", "User Management", url: "/admin/users", requiredPermissionName: "Administration.UserManagement")); - administration.AddItem(new ApplicationMenuItem("Administration.RoleManagement", "Role Management", url: "/admin/roles", requiredPermissionName: "Administration.RoleManagement")); + administration.AddItem(new ApplicationMenuItem("Administration.UserManagement", "User Management", url: "/admin/users").RequirePermissions("Administration.UserManagement")); + administration.AddItem(new ApplicationMenuItem("Administration.RoleManagement", "Role Management", url: "/admin/roles").RequirePermissions("Administration.RoleManagement")); return Task.CompletedTask; } @@ -94,16 +95,16 @@ namespace Volo.Abp.UI.Navigation return Task.CompletedTask; } - context.Menu.Items.Insert(0, new ApplicationMenuItem("Dashboard", "Dashboard", url: "/dashboard", requiredPermissionName: "Dashboard")); + context.Menu.Items.Insert(0, new ApplicationMenuItem("Dashboard", "Dashboard", url: "/dashboard").RequirePermissions("Dashboard")); var administration = context.Menu.GetAdministration(); - administration.AddItem(new ApplicationMenuItem("Administration.DashboardSettings", "Dashboard Settings", url: "/admin/settings/dashboard", requiredPermissionName: "Administration.DashboardSettings")); + administration.AddItem(new ApplicationMenuItem("Administration.DashboardSettings", "Dashboard Settings", url: "/admin/settings/dashboard").RequirePermissions("Administration.DashboardSettings")); administration.AddItem( new ApplicationMenuItem("Administration.SubMenu1", "Sub menu 1", url: "/submenu1") - .AddItem(new ApplicationMenuItem("Administration.SubMenu1.1", "Sub menu 1.1", url: "/submenu1/submenu1_1", requiredPermissionName: "Administration.SubMenu1.1")) - .AddItem(new ApplicationMenuItem("Administration.SubMenu1.2", "Sub menu 1.2", url: "/submenu1/submenu1_2", requiredPermissionName: "Administration.SubMenu1.2")) + .AddItem(new ApplicationMenuItem("Administration.SubMenu1.1", "Sub menu 1.1", url: "/submenu1/submenu1_1").RequirePermissions("Administration.SubMenu1.1")) + .AddItem(new ApplicationMenuItem("Administration.SubMenu1.2", "Sub menu 1.2", url: "/submenu1/submenu1_2").RequirePermissions("Administration.SubMenu1.2")) ); return Task.CompletedTask; diff --git a/modules/account/Volo.Abp.Account.abpmdl.json b/modules/account/Volo.Abp.Account.abpmdl.json index c6135f99c5..28927ae184 100644 --- a/modules/account/Volo.Abp.Account.abpmdl.json +++ b/modules/account/Volo.Abp.Account.abpmdl.json @@ -1,65 +1,42 @@ { "folders": { - "src": {}, - "test": {} - }, - "imports": { - "Volo.Abp.Identity": { - "path": "../identity/Volo.Abp.Identity.abpmdl.json" - }, - "Volo.Abp.PermissionManagement": { - "path": "../permission-management/Volo.Abp.PermissionManagement.abpmdl.json" + "items": { + "src": {}, + "test": {} } }, "packages": { - "Volo.Abp.Account.Application.Contracts": { - "path": "src/Volo.Abp.Account.Application.Contracts/Volo.Abp.Account.Application.Contracts.csproj", - "folder": "src", - "includes": { - "lib.application.contracts": {} - } + "Volo.Abp.Account.Web": { + "path": "src/Volo.Abp.Account.Web/Volo.Abp.Account.Web.abppkg.json", + "folder": "src" + }, + "Volo.Abp.Account.Web.IdentityServer": { + "path": "src/Volo.Abp.Account.Web.IdentityServer/Volo.Abp.Account.Web.IdentityServer.abppkg.json", + "folder": "src" }, "Volo.Abp.Account.Application": { - "path": "src/Volo.Abp.Account.Application/Volo.Abp.Account.Application.csproj", - "folder": "src", - "includes": { - "lib.application": {} - } + "path": "src/Volo.Abp.Account.Application/Volo.Abp.Account.Application.abppkg.json", + "folder": "src" + }, + "Volo.Abp.Account.Application.Contracts": { + "path": "src/Volo.Abp.Account.Application.Contracts/Volo.Abp.Account.Application.Contracts.abppkg.json", + "folder": "src" }, "Volo.Abp.Account.HttpApi": { - "path": "src/Volo.Abp.Account.HttpApi/Volo.Abp.Account.HttpApi.csproj", - "folder": "src", - "includes": { - "lib.http-api": {} - } + "path": "src/Volo.Abp.Account.HttpApi/Volo.Abp.Account.HttpApi.abppkg.json", + "folder": "src" }, "Volo.Abp.Account.HttpApi.Client": { - "path": "src/Volo.Abp.Account.HttpApi.Client/Volo.Abp.Account.HttpApi.Client.csproj", - "folder": "src", - "includes": { - "lib.http-api-client": {} - } - }, - "Volo.Abp.Account.Web": { - "path": "src/Volo.Abp.Account.Web/Volo.Abp.Account.Web.csproj", - "folder": "src", - "includes": { - "lib.ui.mvc": {} - } - }, - "Volo.Abp.Account.Web.IdentityServer": { - "path": "src/Volo.Abp.Account.IdentityServer/Volo.Abp.Account.IdentityServer.csproj", - "folder": "src", - "includes": { - "lib.ui.mvc": {} - } + "path": "src/Volo.Abp.Account.HttpApi.Client/Volo.Abp.Account.HttpApi.Client.abppkg.json", + "folder": "src" }, "Volo.Abp.Account.Application.Tests": { - "path": "test/Volo.Abp.Account.Application.Tests/Volo.Abp.Account.Application.Tests.csproj", - "folder": "test", - "includes": { - "lib.test": {} - } + "path": "test/Volo.Abp.Account.Application.Tests/Volo.Abp.Account.Application.Tests.abppkg.json", + "folder": "test" + }, + "Volo.Abp.Account.Blazor": { + "path": "src/Volo.Abp.Account.Blazor/Volo.Abp.Account.Blazor.abppkg.json", + "folder": "src" } } } \ No newline at end of file diff --git a/modules/account/src/Volo.Abp.Account.Application.Contracts/Volo.Abp.Account.Application.Contracts.abppkg.json b/modules/account/src/Volo.Abp.Account.Application.Contracts/Volo.Abp.Account.Application.Contracts.abppkg.json new file mode 100644 index 0000000000..49032794e2 --- /dev/null +++ b/modules/account/src/Volo.Abp.Account.Application.Contracts/Volo.Abp.Account.Application.Contracts.abppkg.json @@ -0,0 +1,3 @@ +{ + "role": "lib.application-contracts" +} \ No newline at end of file diff --git a/modules/account/src/Volo.Abp.Account.Application.Contracts/Volo/Abp/Account/Localization/Resources/hi.json b/modules/account/src/Volo.Abp.Account.Application.Contracts/Volo/Abp/Account/Localization/Resources/hi.json new file mode 100644 index 0000000000..66c31cf9fb --- /dev/null +++ b/modules/account/src/Volo.Abp.Account.Application.Contracts/Volo/Abp/Account/Localization/Resources/hi.json @@ -0,0 +1,67 @@ +{ + "culture": "hi", + "texts": { + "UserName": "उपयोगकर्ता नाम", + "EmailAddress": "ईमेल पता", + "UserNameOrEmailAddress": "उपयोगकर्ता का नाम या ईमेल पता", + "Password": "कुंजिका", + "RememberMe": "मुझे याद रखना", + "UseAnotherServiceToLogin": "लॉग इन करने के लिए किसी अन्य सेवा का उपयोग करें", + "UserLockedOutMessage": "अमान्य लॉगिन प्रयासों के कारण उपयोगकर्ता खाता बंद कर दिया गया है। कृपया थोड़ी देर प्रतीक्षा करें और पुन: प्रयास करें।", + "InvalidUserNameOrPassword": "अमान्य उपयोगकर्ता नाम या पासवर्ड!", + "LoginIsNotAllowed": "आपको लॉगिन करने की अनुमति नहीं है! आपको अपने ईमेल / फोन नंबर की पुष्टि करनी होगी।", + "SelfRegistrationDisabledMessage": "इस आवेदन के लिए स्व-पंजीकरण अक्षम है। नया उपयोगकर्ता पंजीकृत करने के लिए कृपया एप्लिकेशन व्यवस्थापक से संपर्क करें।", + "LocalLoginDisabledMessage": "इस एप्लिकेशन के लिए स्थानीय लॉगिन अक्षम है।", + "Login": "लॉग इन करें", + "Cancel": "रद्द करना", + "Register": "रजिस्टर करें", + "AreYouANewUser": "क्या आप नए उपयोगकर्ता हैं?", + "AlreadyRegistered": "पहले से पंजीकृत?", + "InvalidLoginRequest": "अमान्य लॉगिन अनुरोध", + "ThereAreNoLoginSchemesConfiguredForThisClient": "इस क्लाइंट के लिए कोई लॉगिन योजनाएँ कॉन्फ़िगर नहीं की गई हैं।", + "LogInUsingYourProviderAccount": "अपने {0} खाते का उपयोग करके लॉग इन करें", + "DisplayName:CurrentPassword": "वर्तमान पासवर्ड", + "DisplayName:NewPassword": "नया पासवर्ड", + "DisplayName:NewPasswordConfirm": "नए पासवर्ड की पुष्टि करें", + "PasswordChangedMessage": "तुम्हारा पासवर्ड सफलतापूर्वक बदल दिया गया है।", + "DisplayName:UserName": "उपयोगकर्ता नाम", + "DisplayName:Email": "ईमेल", + "DisplayName:Name": "नाम", + "DisplayName:Surname": "उपनाम", + "DisplayName:Password": "कुंजिका", + "DisplayName:EmailAddress": "ईमेल पता", + "DisplayName:PhoneNumber": "फ़ोन नंबर", + "PersonalSettings": "व्यक्तिगत सेटिंग", + "PersonalSettingsSaved": "व्यक्तिगत सेटिंग्स सहेजे गए", + "PasswordChanged": "पासवर्ड बदला गया", + "NewPasswordConfirmFailed": "कृपया नए पासवर्ड की पुष्टि करें।", + "Manage": "प्रबंधित", + "ManageYourProfile": "अपनी प्रोफ़ाइल प्रबंधित करें", + "DisplayName:Abp.Account.IsSelfRegistrationEnabled": "क्या स्व-पंजीकरण सक्षम है", + "Description:Abp.Account.IsSelfRegistrationEnabled": "उपयोगकर्ता चाहे तो स्वयं या अपने द्वारा खाता पंजीकृत कर सकता है।", + "DisplayName:Abp.Account.EnableLocalLogin": "एक स्थानीय खाते के साथ प्रमाणीकरण", + "Description:Abp.Account.EnableLocalLogin": "इंगित करता है कि सर्वर उपयोगकर्ताओं को स्थानीय खाते से प्रमाणित करने की अनुमति देगा।", + "LoggedOutTitle": "साइन आउट", + "LoggedOutText": "आपको साइन आउट कर दिया गया है और जल्द ही आपको पुनः निर्देशित किया जाएगा।", + "ReturnToText": "{0} पर पुनर्निर्देशित करने के लिए यहां क्लिक करें", + "OrLoginWith": "या इसके साथ लॉगिन करें:", + "ForgotPassword": "पासवर्ड भूल गए?", + "SendPasswordResetLink_Information": "पासवर्ड रीसेट करने के लिए आपके ईमेल पर एक पासवर्ड रीसेट लिंक भेजा जाएगा। यदि आपको कुछ मिनटों के भीतर ईमेल नहीं मिलता है, तो कृपया पुनः प्रयास करें।", + "PasswordResetMailSentMessage": "खाता पुनर्प्राप्ति ईमेल आपके ई-मेल पते पर भेजी जाती है। यदि आप 15 मिनट के भीतर अपने इनबॉक्स में यह ईमेल नहीं देखते हैं, तो इसे अपने जंक मेल फ़ोल्डर में देखें। यदि आप इसे वहां पाते हैं, तो कृपया इसे चिह्नित करें -नहीं जोड़-।", + "ResetPassword": "पासवर्ड रीसेट", + "ConfirmPassword": "पासवर्ड की पुष्टि करें (दोहराएं)", + "ResetPassword_Information": "कृपया अपना नया पासवर्ड दर्ज करें।", + "YourPasswordIsSuccessfullyReset": "आपका पासवर्ड सफलतापूर्वक रीसेट हो गया है।", + "GoToTheApplication": "एप्लिकेशन पर जाएं", + "BackToLogin": "लॉगिन पर वापस जाएं", + "ProfileTab:Password": "पासवर्ड बदलें", + "ProfileTab:PersonalInfo": "व्यक्तिगत जानकारी", + "ReturnToApplication": "आवेदन पर लौटें", + "Volo.Account:InvalidEmailAddress": "दिए गए ईमेल पते को नहीं पा सकते हैं: {0}", + "PasswordReset": "पासवर्ड रीसेट", + "PasswordResetInfoInEmail": "हमें एक खाता पुनर्प्राप्ति अनुरोध प्राप्त हुआ! यदि आपने यह अनुरोध किया है, तो अपना पासवर्ड रीसेट करने के लिए निम्न लिंक पर क्लिक करें।", + "ResetMyPassword": "अपना पासवर्ड रीसेट करें", + "AccessDenied": "पहुंच अस्वीकृत!", + "AccessDeniedMessage": "आपके पास इस संसाधन तक पहुँच नहीं है।" + } +} \ No newline at end of file diff --git a/modules/account/src/Volo.Abp.Account.Application.Contracts/Volo/Abp/Account/Localization/Resources/it.json b/modules/account/src/Volo.Abp.Account.Application.Contracts/Volo/Abp/Account/Localization/Resources/it.json new file mode 100644 index 0000000000..81f781192d --- /dev/null +++ b/modules/account/src/Volo.Abp.Account.Application.Contracts/Volo/Abp/Account/Localization/Resources/it.json @@ -0,0 +1,67 @@ +{ + "culture": "it", + "texts": { + "UserName": "Nome utente", + "EmailAddress": "Indirizzo e-mail", + "UserNameOrEmailAddress": "Username o Indirizzo Email", + "Password": "Parola d'ordine", + "RememberMe": "Ricordati di me", + "UseAnotherServiceToLogin": "Usa un altro servizio per accedere", + "UserLockedOutMessage": "L'account utente è stato bloccato a causa di tentativi di accesso non validi. Attendi qualche istante e riprova.", + "InvalidUserNameOrPassword": "Username o password non validi!", + "LoginIsNotAllowed": "Non sei autorizzato ad accedere! Devi confermare la tua email / numero di telefono.", + "SelfRegistrationDisabledMessage": "L'auto-registrazione è disabilitata per questa applicazione. Contatta l'amministratore dell'applicazione per registrare un nuovo utente.", + "LocalLoginDisabledMessage": "L'accesso locale è disabilitato per questa applicazione.", + "Login": "Login", + "Cancel": "Annulla", + "Register": "Registrati", + "AreYouANewUser": "Sei un nuovo utente?", + "AlreadyRegistered": "Già registrato?", + "InvalidLoginRequest": "Richiesta di accesso non valida", + "ThereAreNoLoginSchemesConfiguredForThisClient": "Non ci sono schemi di accesso configurati per questo client.", + "LogInUsingYourProviderAccount": "Accedi utilizzando il tuo account {0}", + "DisplayName:CurrentPassword": "Password attuale", + "DisplayName:NewPassword": "Nuova password", + "DisplayName:NewPasswordConfirm": "Conferma la nuova password", + "PasswordChangedMessage": "La tua password è stata cambiata con successo.", + "DisplayName:UserName": "Nome utente", + "DisplayName:Email": "E-mail", + "DisplayName:Name": "Nome", + "DisplayName:Surname": "Cognome", + "DisplayName:Password": "Parola d'ordine", + "DisplayName:EmailAddress": "Indirizzo e-mail", + "DisplayName:PhoneNumber": "Numero di telefono", + "PersonalSettings": "Impostazioni personali", + "PersonalSettingsSaved": "Impostazioni personali salvate", + "PasswordChanged": "Password cambiata", + "NewPasswordConfirmFailed": "Conferma la nuova password.", + "Manage": "Gestire", + "ManageYourProfile": "Gestisci il tuo profilo", + "DisplayName:Abp.Account.IsSelfRegistrationEnabled": "L'auto-registrazione è abilitata", + "Description:Abp.Account.IsSelfRegistrationEnabled": "Se un utente può registrare l'account da solo.", + "DisplayName:Abp.Account.EnableLocalLogin": "Autentica con un account locale", + "Description:Abp.Account.EnableLocalLogin": "Indica se il server consentirà agli utenti di autenticarsi con un account locale.", + "LoggedOutTitle": "Disconnesso", + "LoggedOutText": "Sei stato disconnesso e verrai reindirizzato presto.", + "ReturnToText": "Fai clic qui per reindirizzare a {0}", + "OrLoginWith": "Oppure accedi con:", + "ForgotPassword": "Ha dimenticato la password?", + "SendPasswordResetLink_Information": "Un link per reimpostare la password verrà inviato alla tua e-mail per reimpostare la password. Se non ricevi un'email entro pochi minuti, riprova.", + "PasswordResetMailSentMessage": "E-mail di recupero dell'account inviata al tuo indirizzo e-mail. Se non vedi questa email nella tua posta in arrivo entro 15 minuti, cercala nella cartella della posta indesiderata. Se lo trovi lì, contrassegnalo come -Non Junk-.", + "ResetPassword": "Resetta la password", + "ConfirmPassword": "Conferma (ripeti) la password", + "ResetPassword_Information": "Per favore inserisci la tua nuova password.", + "YourPasswordIsSuccessfullyReset": "La tua password è stata reimpostata con successo.", + "GoToTheApplication": "Vai all'applicazione", + "BackToLogin": "Torna al login", + "ProfileTab:Password": "Cambia la password", + "ProfileTab:PersonalInfo": "Informazioni personali", + "ReturnToApplication": "Torna all'applicazione", + "Volo.Account:InvalidEmailAddress": "Impossibile trovare l'indirizzo email fornito: {0}", + "PasswordReset": "Reimpostazione della password", + "PasswordResetInfoInEmail": "Abbiamo ricevuto una richiesta di recupero dell'account! Se hai avviato questa richiesta, fai clic sul seguente collegamento per reimpostare la password.", + "ResetMyPassword": "Reimposta la mia password", + "AccessDenied": "Accesso negato!", + "AccessDeniedMessage": "Non hai accesso a questa risorsa." + } +} \ No newline at end of file diff --git a/modules/account/src/Volo.Abp.Account.Application/Volo.Abp.Account.Application.abppkg.json b/modules/account/src/Volo.Abp.Account.Application/Volo.Abp.Account.Application.abppkg.json new file mode 100644 index 0000000000..412567ac33 --- /dev/null +++ b/modules/account/src/Volo.Abp.Account.Application/Volo.Abp.Account.Application.abppkg.json @@ -0,0 +1,3 @@ +{ + "role": "lib.application" +} \ No newline at end of file diff --git a/modules/account/src/Volo.Abp.Account.Blazor/Volo.Abp.Account.Blazor.abppkg.json b/modules/account/src/Volo.Abp.Account.Blazor/Volo.Abp.Account.Blazor.abppkg.json new file mode 100644 index 0000000000..19c29b7b8b --- /dev/null +++ b/modules/account/src/Volo.Abp.Account.Blazor/Volo.Abp.Account.Blazor.abppkg.json @@ -0,0 +1,3 @@ +{ + "role": "lib.blazor" +} \ No newline at end of file diff --git a/modules/account/src/Volo.Abp.Account.HttpApi.Client/Volo.Abp.Account.HttpApi.Client.abppkg.json b/modules/account/src/Volo.Abp.Account.HttpApi.Client/Volo.Abp.Account.HttpApi.Client.abppkg.json new file mode 100644 index 0000000000..7deef5e383 --- /dev/null +++ b/modules/account/src/Volo.Abp.Account.HttpApi.Client/Volo.Abp.Account.HttpApi.Client.abppkg.json @@ -0,0 +1,3 @@ +{ + "role": "lib.http-api-client" +} \ No newline at end of file diff --git a/modules/account/src/Volo.Abp.Account.HttpApi/Volo.Abp.Account.HttpApi.abppkg.json b/modules/account/src/Volo.Abp.Account.HttpApi/Volo.Abp.Account.HttpApi.abppkg.json new file mode 100644 index 0000000000..515bfe64c4 --- /dev/null +++ b/modules/account/src/Volo.Abp.Account.HttpApi/Volo.Abp.Account.HttpApi.abppkg.json @@ -0,0 +1,3 @@ +{ + "role": "lib.http-api" +} \ No newline at end of file diff --git a/modules/account/src/Volo.Abp.Account.Web.IdentityServer/Volo.Abp.Account.Web.IdentityServer.abppkg.json b/modules/account/src/Volo.Abp.Account.Web.IdentityServer/Volo.Abp.Account.Web.IdentityServer.abppkg.json new file mode 100644 index 0000000000..9e26dfeeb6 --- /dev/null +++ b/modules/account/src/Volo.Abp.Account.Web.IdentityServer/Volo.Abp.Account.Web.IdentityServer.abppkg.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/modules/account/src/Volo.Abp.Account.Web/Volo.Abp.Account.Web.abppkg.json b/modules/account/src/Volo.Abp.Account.Web/Volo.Abp.Account.Web.abppkg.json new file mode 100644 index 0000000000..930c4018b3 --- /dev/null +++ b/modules/account/src/Volo.Abp.Account.Web/Volo.Abp.Account.Web.abppkg.json @@ -0,0 +1,3 @@ +{ + "role": "lib.mvc" +} \ No newline at end of file diff --git a/modules/account/test/Volo.Abp.Account.Application.Tests/Volo.Abp.Account.Application.Tests.abppkg.json b/modules/account/test/Volo.Abp.Account.Application.Tests/Volo.Abp.Account.Application.Tests.abppkg.json new file mode 100644 index 0000000000..a686451fbc --- /dev/null +++ b/modules/account/test/Volo.Abp.Account.Application.Tests/Volo.Abp.Account.Application.Tests.abppkg.json @@ -0,0 +1,3 @@ +{ + "role": "lib.test" +} \ No newline at end of file diff --git a/modules/audit-logging/Volo.Abp.AuditLogging.abpmdl.json b/modules/audit-logging/Volo.Abp.AuditLogging.abpmdl.json index a21497b1cb..5b2cc3f54b 100644 --- a/modules/audit-logging/Volo.Abp.AuditLogging.abpmdl.json +++ b/modules/audit-logging/Volo.Abp.AuditLogging.abpmdl.json @@ -1,64 +1,42 @@ { "folders": { - "src": {}, - "test": {} + "items": { + "src": {}, + "test": {} + } }, "packages": { "Volo.Abp.AuditLogging.Domain.Shared": { - "path": "src/Volo.Abp.AuditLogging.Domain.Shared/Volo.Abp.AuditLogging.Domain.Shared.csproj", - "folder": "src", - "includes": { - "lib.domain.shared": {} - } + "path": "src/Volo.Abp.AuditLogging.Domain.Shared/Volo.Abp.AuditLogging.Domain.Shared.abppkg.json", + "folder": "src" }, "Volo.Abp.AuditLogging.Domain": { - "path": "src/Volo.Abp.AuditLogging.Domain/Volo.Abp.AuditLogging.Domain.csproj", - "folder": "src", - "includes": { - "lib.domain": {} - } + "path": "src/Volo.Abp.AuditLogging.Domain/Volo.Abp.AuditLogging.Domain.abppkg.json", + "folder": "src" }, "Volo.Abp.AuditLogging.EntityFrameworkCore": { - "path": "src/Volo.Abp.AuditLogging.EntityFrameworkCore/Volo.Abp.AuditLogging.EntityFrameworkCore.csproj", - "folder": "src", - "includes": { - "lib.ef": {} - } + "path": "src/Volo.Abp.AuditLogging.EntityFrameworkCore/Volo.Abp.AuditLogging.EntityFrameworkCore.abppkg.json", + "folder": "src" }, "Volo.Abp.AuditLogging.MongoDB": { - "path": "src/Volo.Abp.AuditLogging.MongoDB/Volo.Abp.AuditLogging.MongoDB.csproj", - "folder": "src", - "includes": { - "lib.mongodb": {} - } - }, - "Volo.Abp.AuditLogging.TestBase": { - "path": "test/Volo.Abp.AuditLogging.TestBase/Volo.Abp.AuditLogging.TestBase.csproj", - "folder": "test", - "includes": { - "lib.test": {} - } + "path": "src/Volo.Abp.AuditLogging.MongoDB/Volo.Abp.AuditLogging.MongoDB.abppkg.json", + "folder": "src" }, "Volo.Abp.AuditLogging.Tests": { - "path": "test/Volo.Abp.AuditLogging.Tests/Volo.Abp.AuditLogging.Tests.csproj", - "folder": "test", - "includes": { - "lib.test": {} - } + "path": "test/Volo.Abp.AuditLogging.Tests/Volo.Abp.AuditLogging.Tests.abppkg.json", + "folder": "test" + }, + "Volo.Abp.AuditLogging.TestBase": { + "path": "test/Volo.Abp.AuditLogging.TestBase/Volo.Abp.AuditLogging.TestBase.abppkg.json", + "folder": "test" }, "Volo.Abp.AuditLogging.EntityFrameworkCore.Tests": { - "path": "test/Volo.Abp.AuditLogging.EntityFrameworkCore.Tests/Volo.Abp.AuditLogging.EntityFrameworkCore.Tests.csproj", - "folder": "test", - "includes": { - "lib.test": {} - } + "path": "test/Volo.Abp.AuditLogging.EntityFrameworkCore.Tests/Volo.Abp.AuditLogging.EntityFrameworkCore.Tests.abppkg.json", + "folder": "test" }, "Volo.Abp.AuditLogging.MongoDB.Tests": { - "path": "test/Volo.Abp.AuditLogging.MongoDB.Tests/Volo.Abp.AuditLogging.MongoDB.Tests.csproj", - "folder": "test", - "includes": { - "lib.test": {} - } + "path": "test/Volo.Abp.AuditLogging.MongoDB.Tests/Volo.Abp.AuditLogging.MongoDB.Tests.abppkg.json", + "folder": "test" } } } \ No newline at end of file diff --git a/modules/audit-logging/src/Volo.Abp.AuditLogging.Domain.Shared/Volo.Abp.AuditLogging.Domain.Shared.abppkg.json b/modules/audit-logging/src/Volo.Abp.AuditLogging.Domain.Shared/Volo.Abp.AuditLogging.Domain.Shared.abppkg.json new file mode 100644 index 0000000000..8b3de05f76 --- /dev/null +++ b/modules/audit-logging/src/Volo.Abp.AuditLogging.Domain.Shared/Volo.Abp.AuditLogging.Domain.Shared.abppkg.json @@ -0,0 +1,3 @@ +{ + "role": "lib.domain-shared" +} \ No newline at end of file diff --git a/modules/audit-logging/src/Volo.Abp.AuditLogging.Domain/Volo.Abp.AuditLogging.Domain.abppkg.json b/modules/audit-logging/src/Volo.Abp.AuditLogging.Domain/Volo.Abp.AuditLogging.Domain.abppkg.json new file mode 100644 index 0000000000..1d574efe45 --- /dev/null +++ b/modules/audit-logging/src/Volo.Abp.AuditLogging.Domain/Volo.Abp.AuditLogging.Domain.abppkg.json @@ -0,0 +1,3 @@ +{ + "role": "lib.domain" +} \ No newline at end of file diff --git a/modules/audit-logging/src/Volo.Abp.AuditLogging.EntityFrameworkCore/Volo.Abp.AuditLogging.EntityFrameworkCore.abppkg.json b/modules/audit-logging/src/Volo.Abp.AuditLogging.EntityFrameworkCore/Volo.Abp.AuditLogging.EntityFrameworkCore.abppkg.json new file mode 100644 index 0000000000..e1c64f0175 --- /dev/null +++ b/modules/audit-logging/src/Volo.Abp.AuditLogging.EntityFrameworkCore/Volo.Abp.AuditLogging.EntityFrameworkCore.abppkg.json @@ -0,0 +1,3 @@ +{ + "role": "lib.ef" +} \ No newline at end of file diff --git a/modules/audit-logging/src/Volo.Abp.AuditLogging.MongoDB/Volo.Abp.AuditLogging.MongoDB.abppkg.json b/modules/audit-logging/src/Volo.Abp.AuditLogging.MongoDB/Volo.Abp.AuditLogging.MongoDB.abppkg.json new file mode 100644 index 0000000000..8b23fd1e69 --- /dev/null +++ b/modules/audit-logging/src/Volo.Abp.AuditLogging.MongoDB/Volo.Abp.AuditLogging.MongoDB.abppkg.json @@ -0,0 +1,3 @@ +{ + "role": "lib.mongodb" +} \ No newline at end of file diff --git a/modules/audit-logging/test/Volo.Abp.AuditLogging.EntityFrameworkCore.Tests/Volo.Abp.AuditLogging.EntityFrameworkCore.Tests.abppkg.json b/modules/audit-logging/test/Volo.Abp.AuditLogging.EntityFrameworkCore.Tests/Volo.Abp.AuditLogging.EntityFrameworkCore.Tests.abppkg.json new file mode 100644 index 0000000000..a686451fbc --- /dev/null +++ b/modules/audit-logging/test/Volo.Abp.AuditLogging.EntityFrameworkCore.Tests/Volo.Abp.AuditLogging.EntityFrameworkCore.Tests.abppkg.json @@ -0,0 +1,3 @@ +{ + "role": "lib.test" +} \ No newline at end of file diff --git a/modules/audit-logging/test/Volo.Abp.AuditLogging.MongoDB.Tests/Volo.Abp.AuditLogging.MongoDB.Tests.abppkg.json b/modules/audit-logging/test/Volo.Abp.AuditLogging.MongoDB.Tests/Volo.Abp.AuditLogging.MongoDB.Tests.abppkg.json new file mode 100644 index 0000000000..a686451fbc --- /dev/null +++ b/modules/audit-logging/test/Volo.Abp.AuditLogging.MongoDB.Tests/Volo.Abp.AuditLogging.MongoDB.Tests.abppkg.json @@ -0,0 +1,3 @@ +{ + "role": "lib.test" +} \ No newline at end of file diff --git a/modules/audit-logging/test/Volo.Abp.AuditLogging.TestBase/Volo.Abp.AuditLogging.TestBase.abppkg.json b/modules/audit-logging/test/Volo.Abp.AuditLogging.TestBase/Volo.Abp.AuditLogging.TestBase.abppkg.json new file mode 100644 index 0000000000..9e26dfeeb6 --- /dev/null +++ b/modules/audit-logging/test/Volo.Abp.AuditLogging.TestBase/Volo.Abp.AuditLogging.TestBase.abppkg.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/modules/audit-logging/test/Volo.Abp.AuditLogging.Tests/Volo.Abp.AuditLogging.Tests.abppkg.json b/modules/audit-logging/test/Volo.Abp.AuditLogging.Tests/Volo.Abp.AuditLogging.Tests.abppkg.json new file mode 100644 index 0000000000..a686451fbc --- /dev/null +++ b/modules/audit-logging/test/Volo.Abp.AuditLogging.Tests/Volo.Abp.AuditLogging.Tests.abppkg.json @@ -0,0 +1,3 @@ +{ + "role": "lib.test" +} \ No newline at end of file diff --git a/modules/background-jobs/Volo.Abp.BackgroundJobs.abpmdl.json b/modules/background-jobs/Volo.Abp.BackgroundJobs.abpmdl.json index da2cab8b84..e3bea65da3 100644 --- a/modules/background-jobs/Volo.Abp.BackgroundJobs.abpmdl.json +++ b/modules/background-jobs/Volo.Abp.BackgroundJobs.abpmdl.json @@ -1,64 +1,63 @@ { "folders": { - "src": {}, - "test": {} + "items": { + "src": {}, + "test": {}, + "app": {} + } }, "packages": { "Volo.Abp.BackgroundJobs.Domain.Shared": { - "path": "src/Volo.Abp.BackgroundJobs.Domain.Shared/Volo.Abp.BackgroundJobs.Domain.Shared.csproj", - "folder": "src", - "includes": { - "lib.domain.shared": {} - } + "path": "src/Volo.Abp.BackgroundJobs.Domain.Shared/Volo.Abp.BackgroundJobs.Domain.Shared.abppkg.json", + "folder": "src" }, "Volo.Abp.BackgroundJobs.Domain": { - "path": "src/Volo.Abp.BackgroundJobs.Domain/Volo.Abp.BackgroundJobs.Domain.csproj", - "folder": "src", - "includes": { - "lib.domain": {} - } + "path": "src/Volo.Abp.BackgroundJobs.Domain/Volo.Abp.BackgroundJobs.Domain.abppkg.json", + "folder": "src" }, "Volo.Abp.BackgroundJobs.EntityFrameworkCore": { - "path": "src/Volo.Abp.BackgroundJobs.EntityFrameworkCore/Volo.Abp.BackgroundJobs.EntityFrameworkCore.csproj", - "folder": "src", - "includes": { - "lib.ef": {} - } + "path": "src/Volo.Abp.BackgroundJobs.EntityFrameworkCore/Volo.Abp.BackgroundJobs.EntityFrameworkCore.abppkg.json", + "folder": "src" }, "Volo.Abp.BackgroundJobs.MongoDB": { - "path": "src/Volo.Abp.BackgroundJobs.MongoDB/Volo.Abp.BackgroundJobs.MongoDB.csproj", - "folder": "src", - "includes": { - "lib.mongodb": {} - } + "path": "src/Volo.Abp.BackgroundJobs.MongoDB/Volo.Abp.BackgroundJobs.MongoDB.abppkg.json", + "folder": "src" }, "Volo.Abp.BackgroundJobs.TestBase": { - "path": "test/Volo.Abp.BackgroundJobs.TestBase/Volo.Abp.BackgroundJobs.TestBase.csproj", - "folder": "test", - "includes": { - "lib.test": {} - } + "path": "test/Volo.Abp.BackgroundJobs.TestBase/Volo.Abp.BackgroundJobs.TestBase.abppkg.json", + "folder": "test" }, "Volo.Abp.BackgroundJobs.Domain.Tests": { - "path": "test/Volo.Abp.BackgroundJobs.Domain.Tests/Volo.Abp.BackgroundJobs.Domain.Tests.csproj", - "folder": "test", - "includes": { - "lib.test": {} - } + "path": "test/Volo.Abp.BackgroundJobs.Domain.Tests/Volo.Abp.BackgroundJobs.Domain.Tests.abppkg.json", + "folder": "test" }, "Volo.Abp.BackgroundJobs.EntityFrameworkCore.Tests": { - "path": "test/Volo.Abp.BackgroundJobs.EntityFrameworkCore.Tests/Volo.Abp.BackgroundJobs.EntityFrameworkCore.Tests.csproj", - "folder": "test", - "includes": { - "lib.test": {} - } + "path": "test/Volo.Abp.BackgroundJobs.EntityFrameworkCore.Tests/Volo.Abp.BackgroundJobs.EntityFrameworkCore.Tests.abppkg.json", + "folder": "test" }, "Volo.Abp.BackgroundJobs.MongoDB.Tests": { - "path": "test/Volo.Abp.BackgroundJobs.MongoDB.Tests/Volo.Abp.BackgroundJobs.MongoDB.Tests.csproj", - "folder": "test", - "includes": { - "lib.test": {} - } + "path": "test/Volo.Abp.BackgroundJobs.MongoDB.Tests/Volo.Abp.BackgroundJobs.MongoDB.Tests.abppkg.json", + "folder": "test" + }, + "Volo.Abp.BackgroundJobs.DemoApp": { + "path": "app/Volo.Abp.BackgroundJobs.DemoApp/Volo.Abp.BackgroundJobs.DemoApp.abppkg.json", + "folder": "app" + }, + "Volo.Abp.BackgroundJobs.DemoApp.Shared": { + "path": "app/Volo.Abp.BackgroundJobs.DemoApp.Shared/Volo.Abp.BackgroundJobs.DemoApp.Shared.abppkg.json", + "folder": "app" + }, + "Volo.Abp.BackgroundJobs.DemoApp.HangFire": { + "path": "app/Volo.Abp.BackgroundJobs.DemoApp.HangFire/Volo.Abp.BackgroundJobs.DemoApp.HangFire.abppkg.json", + "folder": "app" + }, + "Volo.Abp.BackgroundJobs.DemoApp.RabbitMq": { + "path": "app/Volo.Abp.BackgroundJobs.DemoApp.RabbitMq/Volo.Abp.BackgroundJobs.DemoApp.RabbitMq.abppkg.json", + "folder": "app" + }, + "Volo.Abp.BackgroundJobs.DemoApp.Quartz": { + "path": "app/Volo.Abp.BackgroundJobs.DemoApp.Quartz/Volo.Abp.BackgroundJobs.DemoApp.Quartz.abppkg.json", + "folder": "app" } } } \ No newline at end of file diff --git a/modules/background-jobs/app/Volo.Abp.BackgroundJobs.DemoApp.HangFire/Volo.Abp.BackgroundJobs.DemoApp.HangFire.abppkg.json b/modules/background-jobs/app/Volo.Abp.BackgroundJobs.DemoApp.HangFire/Volo.Abp.BackgroundJobs.DemoApp.HangFire.abppkg.json new file mode 100644 index 0000000000..9e26dfeeb6 --- /dev/null +++ b/modules/background-jobs/app/Volo.Abp.BackgroundJobs.DemoApp.HangFire/Volo.Abp.BackgroundJobs.DemoApp.HangFire.abppkg.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/modules/background-jobs/app/Volo.Abp.BackgroundJobs.DemoApp.Quartz/Volo.Abp.BackgroundJobs.DemoApp.Quartz.abppkg.json b/modules/background-jobs/app/Volo.Abp.BackgroundJobs.DemoApp.Quartz/Volo.Abp.BackgroundJobs.DemoApp.Quartz.abppkg.json new file mode 100644 index 0000000000..9e26dfeeb6 --- /dev/null +++ b/modules/background-jobs/app/Volo.Abp.BackgroundJobs.DemoApp.Quartz/Volo.Abp.BackgroundJobs.DemoApp.Quartz.abppkg.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/modules/background-jobs/app/Volo.Abp.BackgroundJobs.DemoApp.RabbitMq/Volo.Abp.BackgroundJobs.DemoApp.RabbitMq.abppkg.json b/modules/background-jobs/app/Volo.Abp.BackgroundJobs.DemoApp.RabbitMq/Volo.Abp.BackgroundJobs.DemoApp.RabbitMq.abppkg.json new file mode 100644 index 0000000000..9e26dfeeb6 --- /dev/null +++ b/modules/background-jobs/app/Volo.Abp.BackgroundJobs.DemoApp.RabbitMq/Volo.Abp.BackgroundJobs.DemoApp.RabbitMq.abppkg.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/modules/background-jobs/app/Volo.Abp.BackgroundJobs.DemoApp.Shared/Volo.Abp.BackgroundJobs.DemoApp.Shared.abppkg.json b/modules/background-jobs/app/Volo.Abp.BackgroundJobs.DemoApp.Shared/Volo.Abp.BackgroundJobs.DemoApp.Shared.abppkg.json new file mode 100644 index 0000000000..9e26dfeeb6 --- /dev/null +++ b/modules/background-jobs/app/Volo.Abp.BackgroundJobs.DemoApp.Shared/Volo.Abp.BackgroundJobs.DemoApp.Shared.abppkg.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/modules/background-jobs/app/Volo.Abp.BackgroundJobs.DemoApp/Volo.Abp.BackgroundJobs.DemoApp.abppkg.json b/modules/background-jobs/app/Volo.Abp.BackgroundJobs.DemoApp/Volo.Abp.BackgroundJobs.DemoApp.abppkg.json new file mode 100644 index 0000000000..9e26dfeeb6 --- /dev/null +++ b/modules/background-jobs/app/Volo.Abp.BackgroundJobs.DemoApp/Volo.Abp.BackgroundJobs.DemoApp.abppkg.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/modules/background-jobs/src/Volo.Abp.BackgroundJobs.Domain.Shared/Volo.Abp.BackgroundJobs.Domain.Shared.abppkg.json b/modules/background-jobs/src/Volo.Abp.BackgroundJobs.Domain.Shared/Volo.Abp.BackgroundJobs.Domain.Shared.abppkg.json new file mode 100644 index 0000000000..8b3de05f76 --- /dev/null +++ b/modules/background-jobs/src/Volo.Abp.BackgroundJobs.Domain.Shared/Volo.Abp.BackgroundJobs.Domain.Shared.abppkg.json @@ -0,0 +1,3 @@ +{ + "role": "lib.domain-shared" +} \ No newline at end of file diff --git a/modules/background-jobs/src/Volo.Abp.BackgroundJobs.Domain/Volo.Abp.BackgroundJobs.Domain.abppkg.json b/modules/background-jobs/src/Volo.Abp.BackgroundJobs.Domain/Volo.Abp.BackgroundJobs.Domain.abppkg.json new file mode 100644 index 0000000000..1d574efe45 --- /dev/null +++ b/modules/background-jobs/src/Volo.Abp.BackgroundJobs.Domain/Volo.Abp.BackgroundJobs.Domain.abppkg.json @@ -0,0 +1,3 @@ +{ + "role": "lib.domain" +} \ No newline at end of file diff --git a/modules/background-jobs/src/Volo.Abp.BackgroundJobs.EntityFrameworkCore/Volo.Abp.BackgroundJobs.EntityFrameworkCore.abppkg.json b/modules/background-jobs/src/Volo.Abp.BackgroundJobs.EntityFrameworkCore/Volo.Abp.BackgroundJobs.EntityFrameworkCore.abppkg.json new file mode 100644 index 0000000000..e1c64f0175 --- /dev/null +++ b/modules/background-jobs/src/Volo.Abp.BackgroundJobs.EntityFrameworkCore/Volo.Abp.BackgroundJobs.EntityFrameworkCore.abppkg.json @@ -0,0 +1,3 @@ +{ + "role": "lib.ef" +} \ No newline at end of file diff --git a/modules/background-jobs/src/Volo.Abp.BackgroundJobs.MongoDB/Volo.Abp.BackgroundJobs.MongoDB.abppkg.json b/modules/background-jobs/src/Volo.Abp.BackgroundJobs.MongoDB/Volo.Abp.BackgroundJobs.MongoDB.abppkg.json new file mode 100644 index 0000000000..8b23fd1e69 --- /dev/null +++ b/modules/background-jobs/src/Volo.Abp.BackgroundJobs.MongoDB/Volo.Abp.BackgroundJobs.MongoDB.abppkg.json @@ -0,0 +1,3 @@ +{ + "role": "lib.mongodb" +} \ No newline at end of file diff --git a/modules/background-jobs/test/Volo.Abp.BackgroundJobs.Domain.Tests/Volo.Abp.BackgroundJobs.Domain.Tests.abppkg.json b/modules/background-jobs/test/Volo.Abp.BackgroundJobs.Domain.Tests/Volo.Abp.BackgroundJobs.Domain.Tests.abppkg.json new file mode 100644 index 0000000000..a686451fbc --- /dev/null +++ b/modules/background-jobs/test/Volo.Abp.BackgroundJobs.Domain.Tests/Volo.Abp.BackgroundJobs.Domain.Tests.abppkg.json @@ -0,0 +1,3 @@ +{ + "role": "lib.test" +} \ No newline at end of file diff --git a/modules/background-jobs/test/Volo.Abp.BackgroundJobs.EntityFrameworkCore.Tests/Volo.Abp.BackgroundJobs.EntityFrameworkCore.Tests.abppkg.json b/modules/background-jobs/test/Volo.Abp.BackgroundJobs.EntityFrameworkCore.Tests/Volo.Abp.BackgroundJobs.EntityFrameworkCore.Tests.abppkg.json new file mode 100644 index 0000000000..a686451fbc --- /dev/null +++ b/modules/background-jobs/test/Volo.Abp.BackgroundJobs.EntityFrameworkCore.Tests/Volo.Abp.BackgroundJobs.EntityFrameworkCore.Tests.abppkg.json @@ -0,0 +1,3 @@ +{ + "role": "lib.test" +} \ No newline at end of file diff --git a/modules/background-jobs/test/Volo.Abp.BackgroundJobs.MongoDB.Tests/Volo.Abp.BackgroundJobs.MongoDB.Tests.abppkg.json b/modules/background-jobs/test/Volo.Abp.BackgroundJobs.MongoDB.Tests/Volo.Abp.BackgroundJobs.MongoDB.Tests.abppkg.json new file mode 100644 index 0000000000..a686451fbc --- /dev/null +++ b/modules/background-jobs/test/Volo.Abp.BackgroundJobs.MongoDB.Tests/Volo.Abp.BackgroundJobs.MongoDB.Tests.abppkg.json @@ -0,0 +1,3 @@ +{ + "role": "lib.test" +} \ No newline at end of file diff --git a/modules/background-jobs/test/Volo.Abp.BackgroundJobs.TestBase/Volo.Abp.BackgroundJobs.TestBase.abppkg.json b/modules/background-jobs/test/Volo.Abp.BackgroundJobs.TestBase/Volo.Abp.BackgroundJobs.TestBase.abppkg.json new file mode 100644 index 0000000000..9e26dfeeb6 --- /dev/null +++ b/modules/background-jobs/test/Volo.Abp.BackgroundJobs.TestBase/Volo.Abp.BackgroundJobs.TestBase.abppkg.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/modules/blob-storing-database/Volo.Abp.BlobStoring.Database.abpmdl.json b/modules/blob-storing-database/Volo.Abp.BlobStoring.Database.abpmdl.json index 2d5e84ad96..f5f118cbdc 100644 --- a/modules/blob-storing-database/Volo.Abp.BlobStoring.Database.abpmdl.json +++ b/modules/blob-storing-database/Volo.Abp.BlobStoring.Database.abpmdl.json @@ -1,64 +1,55 @@ { "folders": { - "src": {}, - "test": {} + "items": { + "src": {}, + "test": {}, + "host": { + "items": { + "BlobStoring.Database.Host.ConsoleApp": { + "items": { + "src": {} + } + } + } + } + } }, "packages": { "Volo.Abp.BlobStoring.Database.Domain.Shared": { - "path": "src/Volo.Abp.BlobStoring.Database.Domain.Shared/Volo.Abp.BlobStoring.Database.Domain.Shared.csproj", - "folder": "src", - "includes": { - "lib.domain.shared": {} - } + "path": "src/Volo.Abp.BlobStoring.Database.Domain.Shared/Volo.Abp.BlobStoring.Database.Domain.Shared.abppkg.json", + "folder": "src" }, "Volo.Abp.BlobStoring.Database.Domain": { - "path": "src/Volo.Abp.BlobStoring.Database.Domain/Volo.Abp.BlobStoring.Database.Domain.csproj", - "folder": "src", - "includes": { - "lib.domain": {} - } + "path": "src/Volo.Abp.BlobStoring.Database.Domain/Volo.Abp.BlobStoring.Database.Domain.abppkg.json", + "folder": "src" }, "Volo.Abp.BlobStoring.Database.EntityFrameworkCore": { - "path": "src/Volo.Abp.BlobStoring.Database.EntityFrameworkCore/Volo.Abp.BlobStoring.Database.EntityFrameworkCore.csproj", - "folder": "src", - "includes": { - "lib.ef": {} - } + "path": "src/Volo.Abp.BlobStoring.Database.EntityFrameworkCore/Volo.Abp.BlobStoring.Database.EntityFrameworkCore.abppkg.json", + "folder": "src" }, "Volo.Abp.BlobStoring.Database.MongoDB": { - "path": "src/Volo.Abp.BlobStoring.Database.MongoDB/Volo.Abp.BlobStoring.Database.MongoDB.csproj", - "folder": "src", - "includes": { - "lib.mongodb": {} - } + "path": "src/Volo.Abp.BlobStoring.Database.MongoDB/Volo.Abp.BlobStoring.Database.MongoDB.abppkg.json", + "folder": "src" }, "Volo.Abp.BlobStoring.Database.TestBase": { - "path": "test/Volo.Abp.BlobStoring.Database.TestBase/Volo.Abp.BlobStoring.Database.TestBase.csproj", - "folder": "test", - "includes": { - "lib.test": {} - } - }, - "Volo.Abp.BlobStoring.Database.Domain.Tests": { - "path": "test/Volo.Abp.BlobStoring.Database.Domain.Tests/Volo.Abp.BlobStoring.Database.Domain.Tests.csproj", - "folder": "test", - "includes": { - "lib.test": {} - } + "path": "test/Volo.Abp.BlobStoring.Database.TestBase/Volo.Abp.BlobStoring.Database.TestBase.abppkg.json", + "folder": "test" }, "Volo.Abp.BlobStoring.Database.EntityFrameworkCore.Tests": { - "path": "test/Volo.Abp.BlobStoring.Database.EntityFrameworkCore.Tests/Volo.Abp.BlobStoring.Database.EntityFrameworkCore.Tests.csproj", - "folder": "test", - "includes": { - "lib.test": {} - } + "path": "test/Volo.Abp.BlobStoring.Database.EntityFrameworkCore.Tests/Volo.Abp.BlobStoring.Database.EntityFrameworkCore.Tests.abppkg.json", + "folder": "test" }, "Volo.Abp.BlobStoring.Database.MongoDB.Tests": { - "path": "test/Volo.Abp.BlobStoring.Database.MongoDB.Tests/Volo.Abp.BlobStoring.Database.MongoDB.Tests.csproj", - "folder": "test", - "includes": { - "lib.test": {} - } + "path": "test/Volo.Abp.BlobStoring.Database.MongoDB.Tests/Volo.Abp.BlobStoring.Database.MongoDB.Tests.abppkg.json", + "folder": "test" + }, + "Volo.Abp.BlobStoring.Database.Domain.Tests": { + "path": "test/Volo.Abp.BlobStoring.Database.Domain.Tests/Volo.Abp.BlobStoring.Database.Domain.Tests.abppkg.json", + "folder": "test" + }, + "BlobStoring.Database.Host.ConsoleApp.ConsoleApp": { + "path": "host/BlobStoring.Database.Host.ConsoleApp/src/BlobStoring.Database.Host.ConsoleApp.ConsoleApp/BlobStoring.Database.Host.ConsoleApp.ConsoleApp.abppkg.json", + "folder": "host/BlobStoring.Database.Host.ConsoleApp/src" } } } \ No newline at end of file diff --git a/modules/blob-storing-database/Volo.Abp.BlobStoring.Database.abpsln.json b/modules/blob-storing-database/Volo.Abp.BlobStoring.Database.abpsln.json index 3261567c56..e90f5d10ff 100644 --- a/modules/blob-storing-database/Volo.Abp.BlobStoring.Database.abpsln.json +++ b/modules/blob-storing-database/Volo.Abp.BlobStoring.Database.abpsln.json @@ -2,6 +2,9 @@ "modules": { "Volo.Abp.BlobStoring.Database": { "path": "Volo.Abp.BlobStoring.Database.abpmdl.json" + }, + "BlobStoring.Database.Host.ConsoleApp": { + "path": "host/BlobStoring.Database.Host.ConsoleApp/BlobStoring.Database.Host.ConsoleApp.abpmdl.json" } } } \ No newline at end of file diff --git a/modules/blob-storing-database/host/BlobStoring.Database.Host.ConsoleApp/BlobStoring.Database.Host.ConsoleApp.abpmdl.json b/modules/blob-storing-database/host/BlobStoring.Database.Host.ConsoleApp/BlobStoring.Database.Host.ConsoleApp.abpmdl.json new file mode 100644 index 0000000000..e8b2a715c8 --- /dev/null +++ b/modules/blob-storing-database/host/BlobStoring.Database.Host.ConsoleApp/BlobStoring.Database.Host.ConsoleApp.abpmdl.json @@ -0,0 +1,13 @@ +{ + "folders": { + "items": { + "src": {} + } + }, + "packages": { + "BlobStoring.Database.Host.ConsoleApp.ConsoleApp": { + "path": "src/BlobStoring.Database.Host.ConsoleApp.ConsoleApp/BlobStoring.Database.Host.ConsoleApp.ConsoleApp.abppkg.json", + "folder": "src" + } + } +} \ No newline at end of file diff --git a/modules/blob-storing-database/host/BlobStoring.Database.Host.ConsoleApp/src/BlobStoring.Database.Host.ConsoleApp.ConsoleApp/BlobStoring.Database.Host.ConsoleApp.ConsoleApp.abppkg.json b/modules/blob-storing-database/host/BlobStoring.Database.Host.ConsoleApp/src/BlobStoring.Database.Host.ConsoleApp.ConsoleApp/BlobStoring.Database.Host.ConsoleApp.ConsoleApp.abppkg.json new file mode 100644 index 0000000000..9e26dfeeb6 --- /dev/null +++ b/modules/blob-storing-database/host/BlobStoring.Database.Host.ConsoleApp/src/BlobStoring.Database.Host.ConsoleApp.ConsoleApp/BlobStoring.Database.Host.ConsoleApp.ConsoleApp.abppkg.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/modules/blob-storing-database/src/Volo.Abp.BlobStoring.Database.Domain.Shared/Volo.Abp.BlobStoring.Database.Domain.Shared.abppkg.json b/modules/blob-storing-database/src/Volo.Abp.BlobStoring.Database.Domain.Shared/Volo.Abp.BlobStoring.Database.Domain.Shared.abppkg.json new file mode 100644 index 0000000000..8b3de05f76 --- /dev/null +++ b/modules/blob-storing-database/src/Volo.Abp.BlobStoring.Database.Domain.Shared/Volo.Abp.BlobStoring.Database.Domain.Shared.abppkg.json @@ -0,0 +1,3 @@ +{ + "role": "lib.domain-shared" +} \ No newline at end of file diff --git a/modules/blob-storing-database/src/Volo.Abp.BlobStoring.Database.Domain.Shared/Volo/Abp/BlobStoring/Database/Localization/hi.json b/modules/blob-storing-database/src/Volo.Abp.BlobStoring.Database.Domain.Shared/Volo/Abp/BlobStoring/Database/Localization/hi.json new file mode 100644 index 0000000000..35062bd727 --- /dev/null +++ b/modules/blob-storing-database/src/Volo.Abp.BlobStoring.Database.Domain.Shared/Volo/Abp/BlobStoring/Database/Localization/hi.json @@ -0,0 +1,6 @@ +{ + "culture": "hi", + "texts": { + "ManageYourProfile": "अपनी प्रोफ़ाइल प्रबंधित करें" + } +} \ No newline at end of file diff --git a/modules/blob-storing-database/src/Volo.Abp.BlobStoring.Database.Domain.Shared/Volo/Abp/BlobStoring/Database/Localization/it.json b/modules/blob-storing-database/src/Volo.Abp.BlobStoring.Database.Domain.Shared/Volo/Abp/BlobStoring/Database/Localization/it.json new file mode 100644 index 0000000000..d0b87bd9d3 --- /dev/null +++ b/modules/blob-storing-database/src/Volo.Abp.BlobStoring.Database.Domain.Shared/Volo/Abp/BlobStoring/Database/Localization/it.json @@ -0,0 +1,6 @@ +{ + "culture": "it", + "texts": { + "ManageYourProfile": "Gestisci il tuo profilo" + } +} \ No newline at end of file diff --git a/modules/blob-storing-database/src/Volo.Abp.BlobStoring.Database.Domain/Volo.Abp.BlobStoring.Database.Domain.abppkg.json b/modules/blob-storing-database/src/Volo.Abp.BlobStoring.Database.Domain/Volo.Abp.BlobStoring.Database.Domain.abppkg.json new file mode 100644 index 0000000000..1d574efe45 --- /dev/null +++ b/modules/blob-storing-database/src/Volo.Abp.BlobStoring.Database.Domain/Volo.Abp.BlobStoring.Database.Domain.abppkg.json @@ -0,0 +1,3 @@ +{ + "role": "lib.domain" +} \ No newline at end of file diff --git a/modules/blob-storing-database/src/Volo.Abp.BlobStoring.Database.EntityFrameworkCore/Volo.Abp.BlobStoring.Database.EntityFrameworkCore.abppkg.json b/modules/blob-storing-database/src/Volo.Abp.BlobStoring.Database.EntityFrameworkCore/Volo.Abp.BlobStoring.Database.EntityFrameworkCore.abppkg.json new file mode 100644 index 0000000000..e1c64f0175 --- /dev/null +++ b/modules/blob-storing-database/src/Volo.Abp.BlobStoring.Database.EntityFrameworkCore/Volo.Abp.BlobStoring.Database.EntityFrameworkCore.abppkg.json @@ -0,0 +1,3 @@ +{ + "role": "lib.ef" +} \ No newline at end of file diff --git a/modules/blob-storing-database/src/Volo.Abp.BlobStoring.Database.MongoDB/Volo.Abp.BlobStoring.Database.MongoDB.abppkg.json b/modules/blob-storing-database/src/Volo.Abp.BlobStoring.Database.MongoDB/Volo.Abp.BlobStoring.Database.MongoDB.abppkg.json new file mode 100644 index 0000000000..8b23fd1e69 --- /dev/null +++ b/modules/blob-storing-database/src/Volo.Abp.BlobStoring.Database.MongoDB/Volo.Abp.BlobStoring.Database.MongoDB.abppkg.json @@ -0,0 +1,3 @@ +{ + "role": "lib.mongodb" +} \ No newline at end of file diff --git a/modules/blob-storing-database/test/Volo.Abp.BlobStoring.Database.Domain.Tests/Volo.Abp.BlobStoring.Database.Domain.Tests.abppkg.json b/modules/blob-storing-database/test/Volo.Abp.BlobStoring.Database.Domain.Tests/Volo.Abp.BlobStoring.Database.Domain.Tests.abppkg.json new file mode 100644 index 0000000000..a686451fbc --- /dev/null +++ b/modules/blob-storing-database/test/Volo.Abp.BlobStoring.Database.Domain.Tests/Volo.Abp.BlobStoring.Database.Domain.Tests.abppkg.json @@ -0,0 +1,3 @@ +{ + "role": "lib.test" +} \ No newline at end of file diff --git a/modules/blob-storing-database/test/Volo.Abp.BlobStoring.Database.EntityFrameworkCore.Tests/Volo.Abp.BlobStoring.Database.EntityFrameworkCore.Tests.abppkg.json b/modules/blob-storing-database/test/Volo.Abp.BlobStoring.Database.EntityFrameworkCore.Tests/Volo.Abp.BlobStoring.Database.EntityFrameworkCore.Tests.abppkg.json new file mode 100644 index 0000000000..a686451fbc --- /dev/null +++ b/modules/blob-storing-database/test/Volo.Abp.BlobStoring.Database.EntityFrameworkCore.Tests/Volo.Abp.BlobStoring.Database.EntityFrameworkCore.Tests.abppkg.json @@ -0,0 +1,3 @@ +{ + "role": "lib.test" +} \ No newline at end of file diff --git a/modules/blob-storing-database/test/Volo.Abp.BlobStoring.Database.MongoDB.Tests/Volo.Abp.BlobStoring.Database.MongoDB.Tests.abppkg.json b/modules/blob-storing-database/test/Volo.Abp.BlobStoring.Database.MongoDB.Tests/Volo.Abp.BlobStoring.Database.MongoDB.Tests.abppkg.json new file mode 100644 index 0000000000..a686451fbc --- /dev/null +++ b/modules/blob-storing-database/test/Volo.Abp.BlobStoring.Database.MongoDB.Tests/Volo.Abp.BlobStoring.Database.MongoDB.Tests.abppkg.json @@ -0,0 +1,3 @@ +{ + "role": "lib.test" +} \ No newline at end of file diff --git a/modules/blob-storing-database/test/Volo.Abp.BlobStoring.Database.TestBase/Volo.Abp.BlobStoring.Database.TestBase.abppkg.json b/modules/blob-storing-database/test/Volo.Abp.BlobStoring.Database.TestBase/Volo.Abp.BlobStoring.Database.TestBase.abppkg.json new file mode 100644 index 0000000000..9e26dfeeb6 --- /dev/null +++ b/modules/blob-storing-database/test/Volo.Abp.BlobStoring.Database.TestBase/Volo.Abp.BlobStoring.Database.TestBase.abppkg.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/modules/blogging/src/Volo.Blogging.Admin.Web/BloggingAdminMenuContributor.cs b/modules/blogging/src/Volo.Blogging.Admin.Web/BloggingAdminMenuContributor.cs index 43e4bfca5b..93fe6c60d7 100644 --- a/modules/blogging/src/Volo.Blogging.Admin.Web/BloggingAdminMenuContributor.cs +++ b/modules/blogging/src/Volo.Blogging.Admin.Web/BloggingAdminMenuContributor.cs @@ -1,5 +1,6 @@ using System.Threading.Tasks; using Volo.Abp.UI.Navigation; +using Volo.Abp.Authorization.Permissions; using Volo.Blogging.Localization; namespace Volo.Blogging.Admin @@ -18,9 +19,9 @@ namespace Volo.Blogging.Admin { var l = context.GetLocalizer(); - var managementRootMenuItem = new ApplicationMenuItem("BlogManagement", l["Menu:BlogManagement"], requiredPermissionName: BloggingPermissions.Blogs.Management); + var managementRootMenuItem = new ApplicationMenuItem("BlogManagement", l["Menu:BlogManagement"]).RequirePermissions(BloggingPermissions.Blogs.Management); - managementRootMenuItem.AddItem(new ApplicationMenuItem("BlogManagement.Blogs", l["Menu:Blogs"], "~/Blogging/Admin/Blogs", requiredPermissionName: BloggingPermissions.Blogs.Management)); + managementRootMenuItem.AddItem(new ApplicationMenuItem("BlogManagement.Blogs", l["Menu:Blogs"], "~/Blogging/Admin/Blogs").RequirePermissions(BloggingPermissions.Blogs.Management)); context.Menu.GetAdministration().AddItem(managementRootMenuItem); diff --git a/modules/blogging/src/Volo.Blogging.Domain.Shared/Volo/Blogging/Localization/Resources/hi.json b/modules/blogging/src/Volo.Blogging.Domain.Shared/Volo/Blogging/Localization/Resources/hi.json new file mode 100644 index 0000000000..11b63e96c3 --- /dev/null +++ b/modules/blogging/src/Volo.Blogging.Domain.Shared/Volo/Blogging/Localization/Resources/hi.json @@ -0,0 +1,61 @@ +{ + "culture": "hi", + "texts": { + "Menu:Blogs": "ब्लॉग", + "Menu:BlogManagement": "ब्लॉगिंग", + "Permission:Management": "प्रबंध", + "Permission:Edit": "संपादित करें", + "Permission:Create": "सृजन करना", + "Permission:Delete": "हटाएं", + "Permission:Blogging": "ब्लॉग", + "Permission:Blogs": "ब्लॉग", + "Permission:Posts": "पदों", + "Permission:Tags": "टैग", + "Permission:Comments": "टिप्पणियाँ", + "Permission:ClearCache": "कैश को साफ़ करें", + "Title": "शीर्षक", + "Delete": "हटाएं", + "Reply": "जवाब दे दो", + "ReplyTo": "उत्तर देने के लिए {0}", + "ContinueReading": "जारी रखें पढ़ रहे हैं", + "DaysAgo": "{0} दिन पहले", + "YearsAgo": "{0} साल पहले", + "MonthsAgo": "{0} महीने पहले", + "WeeksAgo": "{0} सप्ताह पहले", + "MinutesAgo": "{0} मिनट पहले", + "SecondsAgo": "{0} सेकंड पहले", + "HoursAgo": "{0} घंटे पहले", + "Now": "अब क", + "Content": "सामग्री", + "SeeAll": "सभी देखें", + "PopularTags": "प्रसिद्ध टग्स", + "WiewsWithCount": "{0} दृश्य", + "LastPosts": "अंतिम पोस्ट", + "LeaveComment": "टिप्पणी दें", + "TagsInThisArticle": "इस लेख में टैग किया गया है", + "Posts": "पदों", + "Edit": "संपादित करें", + "BLOG": "ब्लॉग", + "CommentDeletionWarningMessage": "टिप्पणी हटा दी जाएगी।", + "PostDeletionWarningMessage": "पोस्ट हटा दी जाएगी।", + "BlogDeletionWarningMessage": "ब्लॉग डिलीट हो जाएगा।", + "AreYouSure": "क्या आपको यकीन है?", + "CommentWithCount": "{शून्य टिप्पणियां", + "Comment": "टिप्पणी", + "ShareOnTwitter": "ट्विटर पर साझा करें", + "CoverImage": "कवर छवि", + "CreateANewPost": "एक नई पोस्ट बनाएँ", + "CreateANewBlog": "एक नया ब्लॉग बनाएँ", + "WhatIsNew": "नया क्या है?", + "Name": "नाम", + "ShortName": "संक्षिप्त नाम", + "CreationTime": "रचना समय", + "Description": "विवरण", + "Blogs": "ब्लॉग", + "Tags": "टैग", + "ShareOn": "पर साझा करें", + "TitleLengthWarning": "60 अक्षरों के नीचे अपने शीर्षक का आकार एसईओ के अनुकूल रखें!", + "ClearCache": "कैश को साफ़ करें", + "ClearCacheConfirmationMessage": "क्या आप वाकई कैश साफ़ करना चाहते हैं?" + } +} \ No newline at end of file diff --git a/modules/blogging/src/Volo.Blogging.Domain.Shared/Volo/Blogging/Localization/Resources/it.json b/modules/blogging/src/Volo.Blogging.Domain.Shared/Volo/Blogging/Localization/Resources/it.json new file mode 100644 index 0000000000..c1dc6064de --- /dev/null +++ b/modules/blogging/src/Volo.Blogging.Domain.Shared/Volo/Blogging/Localization/Resources/it.json @@ -0,0 +1,61 @@ +{ + "culture": "it", + "texts": { + "Menu:Blogs": "Blog", + "Menu:BlogManagement": "Blogging", + "Permission:Management": "Gestione", + "Permission:Edit": "modificare", + "Permission:Create": "Creare", + "Permission:Delete": "Elimina", + "Permission:Blogging": "Blog", + "Permission:Blogs": "Blog", + "Permission:Posts": "Messaggi", + "Permission:Tags": "Tag", + "Permission:Comments": "Commenti", + "Permission:ClearCache": "Cancella cache", + "Title": "Titolo", + "Delete": "Elimina", + "Reply": "rispondere", + "ReplyTo": "Rispondi a {0}", + "ContinueReading": "Continua a leggere", + "DaysAgo": "{0} giorni fa", + "YearsAgo": "{0} anni fa", + "MonthsAgo": "{0} mesi fa", + "WeeksAgo": "{0} settimane fa", + "MinutesAgo": "{0} minuti fa", + "SecondsAgo": "{0} secondi fa", + "HoursAgo": "{0} ore fa", + "Now": "adesso", + "Content": "Soddisfare", + "SeeAll": "Vedi tutto", + "PopularTags": "Tag popolari", + "WiewsWithCount": "{0} visualizzazioni", + "LastPosts": "Ultimi messaggi", + "LeaveComment": "Lascia un commento", + "TagsInThisArticle": "Tag in questo articolo", + "Posts": "Messaggi", + "Edit": "modificare", + "BLOG": "BLOG", + "CommentDeletionWarningMessage": "Il commento verrà eliminato.", + "PostDeletionWarningMessage": "Il post verrà eliminato.", + "BlogDeletionWarningMessage": "Il blog verrà eliminato.", + "AreYouSure": "Sei sicuro?", + "CommentWithCount": "{0} commenti", + "Comment": "Commento", + "ShareOnTwitter": "Condividi su Twitter", + "CoverImage": "Immagine di copertina", + "CreateANewPost": "Crea un nuovo post", + "CreateANewBlog": "Crea un nuovo blog", + "WhatIsNew": "Cosa c'è di nuovo?", + "Name": "Nome", + "ShortName": "Nome corto", + "CreationTime": "Tempo di creazione", + "Description": "Descrizione", + "Blogs": "Blog", + "Tags": "Tag", + "ShareOn": "Condividere su", + "TitleLengthWarning": "Mantieni la dimensione del titolo sotto i 60 caratteri per essere SEO friendly!", + "ClearCache": "Cancella cache", + "ClearCacheConfirmationMessage": "Sei sicuro di voler svuotare la cache?" + } +} \ No newline at end of file diff --git a/modules/blogging/src/Volo.Blogging.Web/Pages/Blogs/Posts/Edit.cshtml b/modules/blogging/src/Volo.Blogging.Web/Pages/Blogs/Posts/Edit.cshtml index 1aa239efd7..a4fcbc0414 100644 --- a/modules/blogging/src/Volo.Blogging.Web/Pages/Blogs/Posts/Edit.cshtml +++ b/modules/blogging/src/Volo.Blogging.Web/Pages/Blogs/Posts/Edit.cshtml @@ -7,7 +7,7 @@ @inject IHtmlLocalizer L @model EditModel @{ - ViewBag.PageTitle = "Blog"; + ViewBag.PageTitle = "Edit Blog Post"; } @section styles { diff --git a/modules/blogging/src/Volo.Blogging.Web/Pages/Blogs/Posts/Index.cshtml b/modules/blogging/src/Volo.Blogging.Web/Pages/Blogs/Posts/Index.cshtml index db9644a9ed..c325513079 100644 --- a/modules/blogging/src/Volo.Blogging.Web/Pages/Blogs/Posts/Index.cshtml +++ b/modules/blogging/src/Volo.Blogging.Web/Pages/Blogs/Posts/Index.cshtml @@ -11,7 +11,7 @@ @inject IHtmlLocalizer L @inject BloggingPageHelper BloggingPageHelper @{ - ViewBag.Title = "Blog"; + ViewBag.Title = "Read All Blog Posts"; } @section scripts { diff --git a/modules/blogging/src/Volo.Blogging.Web/Pages/Blogs/Posts/New.cshtml b/modules/blogging/src/Volo.Blogging.Web/Pages/Blogs/Posts/New.cshtml index d57fd1b772..810a0e3203 100644 --- a/modules/blogging/src/Volo.Blogging.Web/Pages/Blogs/Posts/New.cshtml +++ b/modules/blogging/src/Volo.Blogging.Web/Pages/Blogs/Posts/New.cshtml @@ -7,7 +7,7 @@ @inject IHtmlLocalizer L @model NewModel @{ - ViewBag.PageTitle = "Blog"; + ViewBag.PageTitle = "New Blog Post"; } @section styles { diff --git a/modules/cms-kit/host/Volo.CmsKit.HttpApi.Host/CmsKitHttpApiHostModule.cs b/modules/cms-kit/host/Volo.CmsKit.HttpApi.Host/CmsKitHttpApiHostModule.cs index 3fbbde0950..21dfcfc521 100644 --- a/modules/cms-kit/host/Volo.CmsKit.HttpApi.Host/CmsKitHttpApiHostModule.cs +++ b/modules/cms-kit/host/Volo.CmsKit.HttpApi.Host/CmsKitHttpApiHostModule.cs @@ -101,6 +101,8 @@ namespace Volo.CmsKit options.Languages.Add(new LanguageInfo("hu", "hu", "Magyar")); options.Languages.Add(new LanguageInfo("fi", "fi", "Finnish")); options.Languages.Add(new LanguageInfo("fr", "fr", "Français")); + options.Languages.Add(new LanguageInfo("hi", "hi", "Hindi", "in")); + options.Languages.Add(new LanguageInfo("it", "it", "Italian", "it")); options.Languages.Add(new LanguageInfo("pt-BR", "pt-BR", "Português")); options.Languages.Add(new LanguageInfo("ru", "ru", "Русский")); options.Languages.Add(new LanguageInfo("tr", "tr", "Türkçe")); diff --git a/modules/cms-kit/host/Volo.CmsKit.IdentityServer/CmsKitIdentityServerModule.cs b/modules/cms-kit/host/Volo.CmsKit.IdentityServer/CmsKitIdentityServerModule.cs index aaeea11c96..6a8a9d8ae8 100644 --- a/modules/cms-kit/host/Volo.CmsKit.IdentityServer/CmsKitIdentityServerModule.cs +++ b/modules/cms-kit/host/Volo.CmsKit.IdentityServer/CmsKitIdentityServerModule.cs @@ -107,6 +107,8 @@ namespace Volo.CmsKit options.Languages.Add(new LanguageInfo("hu", "hu", "Magyar")); options.Languages.Add(new LanguageInfo("fi", "fi", "Finnish")); options.Languages.Add(new LanguageInfo("fr", "fr", "Français")); + options.Languages.Add(new LanguageInfo("hi", "hi", "Hindi", "in")); + options.Languages.Add(new LanguageInfo("it", "it", "Italian", "it")); options.Languages.Add(new LanguageInfo("pt-BR", "pt-BR", "Português")); options.Languages.Add(new LanguageInfo("ru", "ru", "Русский")); options.Languages.Add(new LanguageInfo("tr", "tr", "Türkçe")); diff --git a/modules/cms-kit/host/Volo.CmsKit.Web.Host/CmsKitWebHostMenuContributor.cs b/modules/cms-kit/host/Volo.CmsKit.Web.Host/CmsKitWebHostMenuContributor.cs index 1f1421546e..66a3364eae 100644 --- a/modules/cms-kit/host/Volo.CmsKit.Web.Host/CmsKitWebHostMenuContributor.cs +++ b/modules/cms-kit/host/Volo.CmsKit.Web.Host/CmsKitWebHostMenuContributor.cs @@ -4,6 +4,7 @@ using Localization.Resources.AbpUi; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Localization; +using Volo.Abp.Authorization.Permissions; using Volo.CmsKit.Localization; using Volo.Abp.UI.Navigation; using Volo.Abp.Users; @@ -31,30 +32,26 @@ namespace Volo.CmsKit private void AddLogoutItemToMenu(MenuConfigurationContext context) { - var currentUser = context.ServiceProvider.GetRequiredService(); var l = context.GetLocalizer(); - if (currentUser.IsAuthenticated) - { - context.Menu.Items.Add(new ApplicationMenuItem( - "Account.Manage", - l["ManageYourProfile"], - $"{_configuration["AuthServer:Authority"].EnsureEndsWith('/')}Account/Manage", - icon: "fa fa-cog", - order: int.MaxValue - 1001, - null, - "_blank") - ); - - - context.Menu.Items.Add(new ApplicationMenuItem( - "Account.Logout", - l["Logout"], - "~/Account/Logout", - "fas fa-power-off", - order: int.MaxValue - 1000 - )); - } + context.Menu.Items.Add(new ApplicationMenuItem( + "Account.Manage", + l["ManageYourProfile"], + $"{_configuration["AuthServer:Authority"].EnsureEndsWith('/')}Account/Manage", + icon: "fa fa-cog", + order: int.MaxValue - 1001, + null, + "_blank" + ).RequireAuthenticated()); + + + context.Menu.Items.Add(new ApplicationMenuItem( + "Account.Logout", + l["Logout"], + "~/Account/Logout", + "fas fa-power-off", + order: int.MaxValue - 1000 + ).RequireAuthenticated()); } } } diff --git a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/CmsKitWebUnifiedModule.cs b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/CmsKitWebUnifiedModule.cs index e518300ebe..2d67664ad3 100644 --- a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/CmsKitWebUnifiedModule.cs +++ b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/CmsKitWebUnifiedModule.cs @@ -128,6 +128,8 @@ namespace Volo.CmsKit options.Languages.Add(new LanguageInfo("hu", "hu", "Magyar")); options.Languages.Add(new LanguageInfo("fi", "fi", "Finnish")); options.Languages.Add(new LanguageInfo("fr", "fr", "Français")); + options.Languages.Add(new LanguageInfo("hi", "hi", "Hindi", "in")); + options.Languages.Add(new LanguageInfo("it", "it", "Italian", "it")); options.Languages.Add(new LanguageInfo("pt-BR", "pt-BR", "Português (Brasil)")); options.Languages.Add(new LanguageInfo("ru", "ru", "Русский")); options.Languages.Add(new LanguageInfo("tr", "tr", "Türkçe")); diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Menus/CmsKitAdminMenuContributor.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Menus/CmsKitAdminMenuContributor.cs index d5d69405b6..7a11c7d73a 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Menus/CmsKitAdminMenuContributor.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Menus/CmsKitAdminMenuContributor.cs @@ -1,6 +1,7 @@ using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; +using Volo.Abp.Authorization.Permissions; using Volo.Abp.GlobalFeatures; using Volo.Abp.UI.Navigation; using Volo.CmsKit.GlobalFeatures; @@ -29,67 +30,46 @@ namespace Volo.CmsKit.Admin.Web.Menus var l = context.GetLocalizer(); var cmsMenus = new List(); - - if (GlobalFeatureManager.Instance.IsEnabled()) - { - if (await context.IsGrantedAsync(CmsKitAdminPermissions.Pages.Default)) - { - cmsMenus.Add(new ApplicationMenuItem( - CmsKitAdminMenus.Pages.PagesMenu, - l["Pages"].Value, - "/Cms/Pages", - "fa fa-file-alt")); - } - } - - if (GlobalFeatureManager.Instance.IsEnabled()) - { - if (await context.IsGrantedAsync(CmsKitAdminPermissions.Blogs.Default)) - { - cmsMenus.Add(new ApplicationMenuItem( - CmsKitAdminMenus.Blogs.BlogsMenu, - l["Blogs"], - "/Cms/Blogs", - "fa fa-blog" - )); - } - if (await context.IsGrantedAsync(CmsKitAdminPermissions.BlogPosts.Default)) - { - cmsMenus.Add(new ApplicationMenuItem( - CmsKitAdminMenus.BlogPosts.BlogPostsMenu, - l["BlogPosts"], - "/Cms/BlogPosts", - "fa fa-file-signature" - )); - } - } - - if (GlobalFeatureManager.Instance.IsEnabled()) - { - if (await context.IsGrantedAsync(CmsKitAdminPermissions.Tags.Default)) - { - cmsMenus.Add(new ApplicationMenuItem( - CmsKitAdminMenus.Tags.TagsMenu, - l["Tags"].Value, - "/Cms/Tags", - "fa fa-tags")); - } - } - - if (GlobalFeatureManager.Instance.IsEnabled()) - { - if (await context.IsGrantedAsync(CmsKitAdminPermissions.Comments.Default)) - { - cmsMenus.Add(new ApplicationMenuItem( - CmsKitAdminMenus.Comments.CommentsMenu, - l["Comments"].Value, - "/Cms/Comments", - "fa fa-comments" - ) - ); - } - } + cmsMenus.Add(new ApplicationMenuItem( + CmsKitAdminMenus.Pages.PagesMenu, + l["Pages"].Value, + "/Cms/Pages", + "fa fa-file-alt") + .RequireGlobalFeatures(typeof(PagesFeature)) + .RequirePermissions(CmsKitAdminPermissions.Pages.Default)); + + cmsMenus.Add(new ApplicationMenuItem( + CmsKitAdminMenus.Blogs.BlogsMenu, + l["Blogs"], + "/Cms/Blogs", + "fa fa-blog") + .RequireGlobalFeatures(typeof(BlogsFeature)) + .RequirePermissions(CmsKitAdminPermissions.Blogs.Default)); + + cmsMenus.Add(new ApplicationMenuItem( + CmsKitAdminMenus.BlogPosts.BlogPostsMenu, + l["BlogPosts"], + "/Cms/BlogPosts", + "fa fa-file-signature") + .RequireGlobalFeatures(typeof(BlogsFeature)) + .RequirePermissions(CmsKitAdminPermissions.BlogPosts.Default)); + + cmsMenus.Add(new ApplicationMenuItem( + CmsKitAdminMenus.Tags.TagsMenu, + l["Tags"].Value, + "/Cms/Tags", + "fa fa-tags") + .RequireGlobalFeatures(typeof(TagsFeature)) + .RequirePermissions(CmsKitAdminPermissions.Tags.Default)); + + cmsMenus.Add(new ApplicationMenuItem( + CmsKitAdminMenus.Comments.CommentsMenu, + l["Comments"].Value, + "/Cms/Comments", + "fa fa-comments") + .RequireGlobalFeatures(typeof(CommentsFeature)) + .RequirePermissions(CmsKitAdminPermissions.Comments.Default)); if (cmsMenus.Any()) { @@ -112,4 +92,4 @@ namespace Volo.CmsKit.Admin.Web.Menus } } } -} \ No newline at end of file +} diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/fr.json b/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/fr.json index 2c36a30214..a95cd21389 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/fr.json +++ b/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/fr.json @@ -4,7 +4,7 @@ "BlogDeletionConfirmationMessage": "Le blog \"{0}\" sera supprimé. Êtes-vous sûr?", "BlogFeatureNotAvailable": "Cette fonctionnalité n'est pas disponible actuellement. Activez avec 'GlobalFeatureManager' pour l'utiliser.", "BlogId": "Blog", - "BlogPostDeletionConfirmationMessage": "Le message de blog \"{0}\" sera supprimé. Êtes-vous sûr?", + "BlogPostDeletionConfirmationMessage": "L'article de blog \"{0}\" sera supprimé. Êtes-vous sûr?", "BlogPosts": "Articles de blog", "Blogs": "Blogs", "ChoosePreference": "Choisissez la préférence ...", @@ -16,7 +16,7 @@ "CmsKit:0002": "Le contenu existe déjà!", "CmsKit:0003": "L'entité {0} ne peut pas être taguée.", "CmsKit:Blog:0001": "Le slug donné ({Slug}) existe déjà!", - "CmsKit:BlogPost:0001": "La limace donnée existe déjà!", + "CmsKit:BlogPost:0001": "Lz slug donné existe déjà!", "CmsKit:Comments:0001": "L'entité {EntityType} ne peut pas être commentée.", "CmsKit:Media:0001": "«{Name}» n'est pas un nom de média valide.", "CmsKit:Media:0002": "L'entité ne peut pas avoir de média.", @@ -42,7 +42,7 @@ "EntityId": "ID d'entité", "EntityType": "Type d'entité", "ExportCSV": "Exporter au format CSV", - "Features": "Caractéristiques", + "Features": "Fonctionnalités", "GenericDeletionConfirmationMessage": "Êtes-vous sûr de vouloir supprimer \"{0}\"?", "LastModification": "Dernière modification", "LoginToAddComment": "Connectez-vous pour ajouter un commentaire", @@ -50,7 +50,7 @@ "LoginToReact": "Connectez-vous pour réagir", "LoginToReply": "Connectez-vous pour répondre", "Menu:CMS": "CMS", - "Message": "Un message", + "Message": "Message", "MessageDeletionConfirmationMessage": "Ce commentaire sera complètement supprimé.", "NewPage": "Nouvelle page", "NewBlog": "Nouveau Blog", @@ -58,12 +58,12 @@ "NewTag": "Nouveau tag", "OK": "d'accord", "PageDeletionConfirmationMessage": "Êtes-vous sûr de vouloir supprimer cette page?", - "Pages": "Des pages", + "Pages": "Pages", "PageSlugInformation": "Slug est utilisé sur l'url. Votre URL sera \"/ pages / {{slug}}\".", "Permission:BlogManagement": "Gestion de blog", "Permission:BlogManagement.Create": "Créer", "Permission:BlogManagement.Delete": "Effacer", - "Permission:BlogManagement.Features": "Caractéristiques", + "Permission:BlogManagement.Features": "Fonctionnalités", "Permission:BlogManagement.Update": "Mettre à jour", "Permission:BlogPostManagement": "Gestion des articles de blog", "Permission:BlogPostManagement.Create": "Créer", diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/hi.json b/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/hi.json new file mode 100644 index 0000000000..084cd76052 --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/hi.json @@ -0,0 +1,135 @@ +{ + "culture": "hi", + "texts": { + "BlogDeletionConfirmationMessage": "ब्लॉग '{0}' हटा दिया जाएगा। क्या आपको यकीन है?", + "BlogFeatureNotAvailable": "यह सुविधा अभी उपलब्ध नहीं है। इसका उपयोग करने के लिए 'GlobalFeatureManager' के साथ सक्षम करें।", + "BlogId": "ब्लॉग", + "BlogPostDeletionConfirmationMessage": "ब्लॉग पोस्ट '{0}' हटा दी जाएगी। क्या आपको यकीन है?", + "BlogPosts": "वेबदैनिकी डाक", + "Blogs": "ब्लॉग", + "ChoosePreference": "पसंद चुनें ...", + "Cms": "मुख्यमंत्रियों", + "CmsKit.Comments": "टिप्पणियाँ", + "CmsKit.Ratings": "रेटिंग्स", + "CmsKit.Reactions": "प्रतिक्रियाओं", + "CmsKit.Tags": "टैग", + "CmsKit:0002": "सामग्री पहले से मौजूद है!", + "CmsKit:0003": "इकाई {0} टैग करने योग्य नहीं है।", + "CmsKit:Blog:0001": "दिया गया स्लग ({स्लग}) पहले से मौजूद है!", + "CmsKit:BlogPost:0001": "दिया गया स्लग पहले से मौजूद है!", + "CmsKit:Comments:0001": "इकाई {EntityType} उल्लेखनीय नहीं है।", + "CmsKit:Media:0001": "'{नाम}' एक मान्य मीडिया नाम नहीं है।", + "CmsKit:Media:0002": "इकाई में मीडिया नहीं हो सकता।", + "CmsKit:Page:0001": "दिया गया url ({स्लग}) पहले से मौजूद है। कृपया अलग-अलग यूआरएल के साथ प्रयास करें।", + "CmsKit:Rating:0001": "इकाई {EntityType} को रेट नहीं किया जा सकता।", + "CmsKit:Reaction:0001": "इकाई {EntityType} में प्रतिक्रियाएं नहीं हो सकती हैं।", + "CmsKit:Tag:0002": "इकाई टैग करने योग्य नहीं है!", + "CommentAuthorizationExceptionMessage": "उन टिप्पणियों को सार्वजनिक प्रदर्शन की अनुमति नहीं है।", + "CommentDeletionConfirmationMessage": "यह टिप्पणी और सभी उत्तर हटा दिए जाएंगे!", + "Comments": "टिप्पणियाँ", + "Content": "सामग्री", + "ContentDeletionConfirmationMessage": "क्या आप इस सामग्री को हटाना सुनिश्चित कर रहे हैं?", + "Contents": "अंतर्वस्तु", + "CoverImage": "कवर छवि", + "CreateBlogPostPage": "नई ब्लॉग पोस्ट", + "CreationTime": "रचना समय", + "Delete": "हटाएं", + "Detail": "विस्तार", + "Details": "विवरण", + "DoYouPreferAdditionalEmails": "क्या आप अतिरिक्त ईमेल पसंद करते हैं?", + "Edit": "संपादित करें", + "EndDate": "समाप्ति तिथि", + "EntityId": "इकाई आईडी", + "EntityType": "इकाई प्रकार", + "ExportCSV": "निर्यात CSV", + "Features": "विशेषताएं", + "GenericDeletionConfirmationMessage": "क्या आप '{0}' को हटाना सुनिश्चित कर रहे हैं?", + "LastModification": "आखरी बदलाव", + "LoginToAddComment": "टिप्पणी जोड़ने के लिए लॉगिन करें", + "LoginToRate": "दर करने के लिए लॉगिन करें", + "LoginToReact": "प्रतिक्रिया करने के लिए लॉगिन करें", + "LoginToReply": "उत्तर देने के लिए प्रवेश करें", + "Menu:CMS": "मुख्यमंत्रियों", + "Message": "संदेश", + "MessageDeletionConfirmationMessage": "यह टिप्पणी पूरी तरह से हटा दी जाएगी।", + "NewPage": "नया पृष्ठ", + "NewBlog": "नया ब्लॉग", + "NewBlogPost": "नई ब्लॉग पोस्ट", + "NewTag": "नया टैग", + "OK": "ठीक है", + "PageDeletionConfirmationMessage": "क्या आप इस पृष्ठ को हटाना सुनिश्चित कर रहे हैं?", + "Pages": "पृष्ठों", + "PageSlugInformation": "स्लग का उपयोग url पर किया जाता है। आपका url '/ Pages / {{slug}}' होगा।", + "Permission:BlogManagement": "ब्लॉग प्रबंधन", + "Permission:BlogManagement.Create": "सृजन करना", + "Permission:BlogManagement.Delete": "हटाएं", + "Permission:BlogManagement.Features": "विशेषताएं", + "Permission:BlogManagement.Update": "अपडेट करें", + "Permission:BlogPostManagement": "ब्लॉग पोस्ट प्रबंधन", + "Permission:BlogPostManagement.Create": "सृजन करना", + "Permission:BlogPostManagement.Delete": "हटाएं", + "Permission:BlogPostManagement.Update": "अपडेट करें", + "Permission:CmsKit": "CmsKit", + "Permission:Comments": "टिप्पणी प्रबंधन", + "Permission:Comments.Delete": "हटाएं", + "Permission:Contents": "सामग्री प्रबंधन", + "Permission:Contents.Create": "सामग्री बनाएँ", + "Permission:Contents.Delete": "सामग्री हटाएं", + "Permission:Contents.Update": "अद्यतन सामग्री", + "Permission:MediaDescriptorManagement": "मीडिया प्रबंधन", + "Permission:MediaDescriptorManagement:Create": "सृजन करना", + "Permission:MediaDescriptorManagement:Delete": "हटाएं", + "Permission:PageManagement": "पेज प्रबंधन", + "Permission:PageManagement:Create": "सृजन करना", + "Permission:PageManagement:Delete": "हटाएं", + "Permission:PageManagement:Update": "अपडेट करें", + "Permission:TagManagement": "टैग प्रबंधन", + "Permission:TagManagement.Create": "सृजन करना", + "Permission:TagManagement.Delete": "हटाएं", + "Permission:TagManagement.Update": "अपडेट करें", + "PickYourReaction": "अपनी प्रतिक्रिया उठाओ", + "Rating": "रेटिंग", + "RatingUndoMessage": "आपकी रेटिंग पूर्ववत होगी।", + "Reactions": "प्रतिक्रियाओं", + "Read": "पढ़ें", + "RepliesToThisComment": "इस टिप्पणी का जवाब", + "Reply": "जवाब दे दो", + "ReplyTo": "को उत्तर", + "SamplePageMessage": "प्रो मॉड्यूल के लिए एक नमूना पृष्ठ", + "SaveChanges": "परिवर्तनों को सुरक्षित करें", + "Script": "लिपि", + "SelectAll": "सभी का चयन करे", + "Send": "संदेश", + "SendMessage": "मेसेज भेजें", + "ShortDescription": "संक्षिप्त वर्णन", + "Slug": "काउंटर", + "Source": "स्रोत", + "SourceUrl": "स्रोत Url", + "Star": "सितारा", + "StartDate": "आरंभ करने की तिथि", + "Style": "अंदाज", + "Subject": "विषय", + "SubjectPlaceholder": "कृपया एक विषय लिखें", + "Submit": "प्रस्तुत", + "Subscribe": "सदस्यता लेने के", + "SuccessfullySaved": "सफलतापूर्वक संचित कर लिया गया है!", + "TagDeletionConfirmationMessage": "क्या आप '{0}' टैग हटाना सुनिश्चित कर रहे हैं?", + "Tags": "टैग", + "Text": "टेक्स्ट", + "ThankYou": "धन्यवाद", + "Title": "शीर्षक", + "Undo": "पूर्ववत", + "Update": "अपडेट करें", + "UpdatePreferenceSuccessMessage": "आपकी प्राथमिकताओं को सुरक्षित किया गया है।", + "UpdateYourEmailPreferences": "अपनी ईमेल प्राथमिकताएँ अपडेट करें", + "UploadFailedMessage": "अपलोड विफल।", + "UserId": "यूज़र आईडी", + "Username": "उपयोगकर्ता नाम", + "YourComment": "आपकी टिप्पणी", + "YourEmailAddress": "आपका ईमेल पता", + "YourFullName": "आपका पूरा नाम", + "YourMessage": "आपका संदेश", + "YourReply": "आपके उत्तर", + "LastModificationTime": "अंतिम संशोधन समय" + } +} \ No newline at end of file diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/it.json b/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/it.json new file mode 100644 index 0000000000..0c5963cc0f --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/it.json @@ -0,0 +1,135 @@ +{ + "culture": "it", + "texts": { + "BlogDeletionConfirmationMessage": "Il blog \"{0}\" verrà eliminato. Sei sicuro?", + "BlogFeatureNotAvailable": "Questa funzione non è ora disponibile. Abilita con \"GlobalFeatureManager\" per usarlo.", + "BlogId": "Blog", + "BlogPostDeletionConfirmationMessage": "Il post del blog \"{0}\" verrà eliminato. Sei sicuro?", + "BlogPosts": "I post del blog", + "Blogs": "Blog", + "ChoosePreference": "Scegli preferenza ...", + "Cms": "CMS", + "CmsKit.Comments": "Commenti", + "CmsKit.Ratings": "Giudizi", + "CmsKit.Reactions": "Reazioni", + "CmsKit.Tags": "Tag", + "CmsKit:0002": "Il contenuto esiste già!", + "CmsKit:0003": "L'entità {0} non è codificabile.", + "CmsKit:Blog:0001": "Lo slug specificato ({Slug}) esiste già!", + "CmsKit:BlogPost:0001": "Lo slug dato esiste già!", + "CmsKit:Comments:0001": "L'entità {EntityType} non è commentabile.", + "CmsKit:Media:0001": "\"{Name}\" non è un nome di supporto valido.", + "CmsKit:Media:0002": "L'entità non può avere media.", + "CmsKit:Page:0001": "L'URL fornito ({Slug}) esiste già. Prova con un URL diverso.", + "CmsKit:Rating:0001": "L'entità {EntityType} non può essere valutata.", + "CmsKit:Reaction:0001": "L'entità {EntityType} non può avere reazioni.", + "CmsKit:Tag:0002": "L'entità non è etichettabile!", + "CommentAuthorizationExceptionMessage": "Tali commenti non sono consentiti per la visualizzazione pubblica.", + "CommentDeletionConfirmationMessage": "Questo commento e tutte le risposte verranno cancellate!", + "Comments": "Commenti", + "Content": "Soddisfare", + "ContentDeletionConfirmationMessage": "Sei sicuro di eliminare questo contenuto?", + "Contents": "Contenuti", + "CoverImage": "Immagine di copertina", + "CreateBlogPostPage": "Nuovo post sul blog", + "CreationTime": "Tempo di creazione", + "Delete": "Elimina", + "Detail": "Dettaglio", + "Details": "Dettagli", + "DoYouPreferAdditionalEmails": "Preferisci email aggiuntive?", + "Edit": "modificare", + "EndDate": "Data di fine", + "EntityId": "Entity Id", + "EntityType": "Tipo di entità", + "ExportCSV": "Esporta CSV", + "Features": "Caratteristiche", + "GenericDeletionConfirmationMessage": "Sei sicuro di eliminare \"{0}\"?", + "LastModification": "Ultima modifica", + "LoginToAddComment": "Accedi per aggiungere un commento", + "LoginToRate": "Accedi per votare", + "LoginToReact": "Accedi per reagire", + "LoginToReply": "Accedi per rispondere", + "Menu:CMS": "CMS", + "Message": "Messaggio", + "MessageDeletionConfirmationMessage": "Questo commento verrà completamente cancellato.", + "NewPage": "Nuova pagina", + "NewBlog": "Nuovo blog", + "NewBlogPost": "Nuovo post sul blog", + "NewTag": "Nuovo tag", + "OK": "ok", + "PageDeletionConfirmationMessage": "Sei sicuro di cancellare questa pagina?", + "Pages": "Pages", + "PageSlugInformation": "Lo slug viene utilizzato sull'URL. Il tuo URL sarà \"/ pages / {{slug}}\".", + "Permission:BlogManagement": "Gestione del blog", + "Permission:BlogManagement.Create": "Creare", + "Permission:BlogManagement.Delete": "Elimina", + "Permission:BlogManagement.Features": "Caratteristiche", + "Permission:BlogManagement.Update": "Aggiornare", + "Permission:BlogPostManagement": "Gestione dei post sul blog", + "Permission:BlogPostManagement.Create": "Creare", + "Permission:BlogPostManagement.Delete": "Elimina", + "Permission:BlogPostManagement.Update": "Aggiornare", + "Permission:CmsKit": "CmsKit", + "Permission:Comments": "Gestione dei commenti", + "Permission:Comments.Delete": "Elimina", + "Permission:Contents": "Gestione dei contenuti", + "Permission:Contents.Create": "Crea contenuto", + "Permission:Contents.Delete": "Elimina contenuto", + "Permission:Contents.Update": "Aggiorna contenuto", + "Permission:MediaDescriptorManagement": "Gestione dei media", + "Permission:MediaDescriptorManagement:Create": "Creare", + "Permission:MediaDescriptorManagement:Delete": "Elimina", + "Permission:PageManagement": "Gestione della pagina", + "Permission:PageManagement:Create": "Creare", + "Permission:PageManagement:Delete": "Elimina", + "Permission:PageManagement:Update": "Aggiornare", + "Permission:TagManagement": "Gestione dei tag", + "Permission:TagManagement.Create": "Creare", + "Permission:TagManagement.Delete": "Elimina", + "Permission:TagManagement.Update": "Aggiornare", + "PickYourReaction": "Scegli la tua reazione", + "Rating": "Valutazione", + "RatingUndoMessage": "La tua valutazione verrà annullata.", + "Reactions": "Reazioni", + "Read": "Leggere", + "RepliesToThisComment": "Risposte a questo commento", + "Reply": "rispondere", + "ReplyTo": "Rispondi a", + "SamplePageMessage": "Una pagina di esempio per il modulo Pro", + "SaveChanges": "Salvare le modifiche", + "Script": "Script", + "SelectAll": "Seleziona tutto", + "Send": "Spedire", + "SendMessage": "Invia messaggio", + "ShortDescription": "Breve descrizione", + "Slug": "Lumaca", + "Source": "fonte", + "SourceUrl": "URL di origine", + "Star": "Stella", + "StartDate": "Data d'inizio", + "Style": "Stile", + "Subject": "Soggetto", + "SubjectPlaceholder": "Si prega di digitare un oggetto", + "Submit": "Invia", + "Subscribe": "sottoscrivi", + "SuccessfullySaved": "Salvato con successo!", + "TagDeletionConfirmationMessage": "Sei sicuro di eliminare il tag \"{0}\"?", + "Tags": "Tag", + "Text": "Testo", + "ThankYou": "Grazie", + "Title": "Titolo", + "Undo": "Disfare", + "Update": "Aggiornare", + "UpdatePreferenceSuccessMessage": "Le tue preferenze sono state salvate.", + "UpdateYourEmailPreferences": "Aggiorna le tue preferenze email", + "UploadFailedMessage": "Caricamento fallito.", + "UserId": "ID utente", + "Username": "Nome utente", + "YourComment": "Il tuo commento", + "YourEmailAddress": "Il tuo indirizzo di posta elettronica", + "YourFullName": "Il tuo nome completo", + "YourMessage": "Il tuo messaggio", + "YourReply": "La tua risposta", + "LastModificationTime": "Ora ultima modifica" + } +} \ No newline at end of file diff --git a/modules/docs/app/VoloDocs.Web/Localization/Resources/VoloDocs/Web/hi.json b/modules/docs/app/VoloDocs.Web/Localization/Resources/VoloDocs/Web/hi.json new file mode 100644 index 0000000000..5f3f4ff985 --- /dev/null +++ b/modules/docs/app/VoloDocs.Web/Localization/Resources/VoloDocs/Web/hi.json @@ -0,0 +1,10 @@ +{ + "culture": "hi", + "texts": { + "DocsTitle": "VoloDocs", + "WelcomeVoloDocs": "VoloDocs में आपका स्वागत है!", + "NoProjectWarning": "अभी तक कोई परिभाषित परियोजना नहीं है!", + "CreateYourFirstProject": "अपना पहला प्रोजेक्ट शुरू करने के लिए यहां क्लिक करें", + "NoProject": "कोई प्रोजेक्ट नहीं!" + } +} \ No newline at end of file diff --git a/modules/docs/app/VoloDocs.Web/Localization/Resources/VoloDocs/Web/it.json b/modules/docs/app/VoloDocs.Web/Localization/Resources/VoloDocs/Web/it.json new file mode 100644 index 0000000000..cc954f2f6d --- /dev/null +++ b/modules/docs/app/VoloDocs.Web/Localization/Resources/VoloDocs/Web/it.json @@ -0,0 +1,10 @@ +{ + "culture": "it", + "texts": { + "DocsTitle": "VoloDocs", + "WelcomeVoloDocs": "Benvenuto in VoloDocs!", + "NoProjectWarning": "Non esiste ancora un progetto definito!", + "CreateYourFirstProject": "Clicca qui per iniziare il tuo primo progetto", + "NoProject": "Nessun progetto!" + } +} \ No newline at end of file diff --git a/modules/docs/app/VoloDocs.Web/VoloDocsWebModule.cs b/modules/docs/app/VoloDocs.Web/VoloDocsWebModule.cs index 9cd7256880..7c9300fc44 100644 --- a/modules/docs/app/VoloDocs.Web/VoloDocsWebModule.cs +++ b/modules/docs/app/VoloDocs.Web/VoloDocsWebModule.cs @@ -125,6 +125,8 @@ namespace VoloDocs.Web options.Languages.Add(new LanguageInfo("en", "en", "English")); options.Languages.Add(new LanguageInfo("fi", "fi", "Finnish")); options.Languages.Add(new LanguageInfo("fr", "fr", "Français")); + options.Languages.Add(new LanguageInfo("hi", "hi", "Hindi", "in")); + options.Languages.Add(new LanguageInfo("it", "it", "Italian", "it")); options.Languages.Add(new LanguageInfo("hu", "hu", "Magyar")); options.Languages.Add(new LanguageInfo("tr", "tr", "Türkçe")); options.Languages.Add(new LanguageInfo("zh-Hans", "zh-Hans", "简体中文")); diff --git a/modules/docs/src/Volo.Docs.Admin.Application.Contracts/Volo/Docs/Admin/Localization/Resources/Docs/ApplicationContracts/FR.json b/modules/docs/src/Volo.Docs.Admin.Application.Contracts/Volo/Docs/Admin/Localization/Resources/Docs/ApplicationContracts/fr.json similarity index 95% rename from modules/docs/src/Volo.Docs.Admin.Application.Contracts/Volo/Docs/Admin/Localization/Resources/Docs/ApplicationContracts/FR.json rename to modules/docs/src/Volo.Docs.Admin.Application.Contracts/Volo/Docs/Admin/Localization/Resources/Docs/ApplicationContracts/fr.json index e585547e8d..2997532840 100644 --- a/modules/docs/src/Volo.Docs.Admin.Application.Contracts/Volo/Docs/Admin/Localization/Resources/Docs/ApplicationContracts/FR.json +++ b/modules/docs/src/Volo.Docs.Admin.Application.Contracts/Volo/Docs/Admin/Localization/Resources/Docs/ApplicationContracts/fr.json @@ -7,8 +7,8 @@ "Permission:Delete": "Effacer", "Permission:Create": "Créer", "Permission:Documents": "Des documents", - "Menu:Documents": "Des documents", - "Menu:DocumentManagement": "Des documents", + "Menu:Documents": "Documents", + "Menu:DocumentManagement": "Documents", "Menu:ProjectManagement": "Projets", "CreateANewProject": "Créer un nouveau projet", "Edit": "Éditer", @@ -36,7 +36,7 @@ "DisplayName:All": "Tirer tout", "DisplayName:LanguageCode": "Code de langue", "DisplayName:Version": "Version", - "Documents": "Des documents", + "Documents": "Documents", "RemoveFromCache": "Retirer du cache", "Reindex": "Réindexer", "ReindexCompleted": "Réindexation terminée", diff --git a/modules/docs/src/Volo.Docs.Admin.Application.Contracts/Volo/Docs/Admin/Localization/Resources/Docs/ApplicationContracts/hi.json b/modules/docs/src/Volo.Docs.Admin.Application.Contracts/Volo/Docs/Admin/Localization/Resources/Docs/ApplicationContracts/hi.json new file mode 100644 index 0000000000..d2a0e11876 --- /dev/null +++ b/modules/docs/src/Volo.Docs.Admin.Application.Contracts/Volo/Docs/Admin/Localization/Resources/Docs/ApplicationContracts/hi.json @@ -0,0 +1,59 @@ +{ + "culture": "hi", + "texts": { + "Permission:DocumentManagement": "दस्तावेज़ प्रबंधन", + "Permission:Projects": "परियोजनाओं", + "Permission:Edit": "संपादित करें", + "Permission:Delete": "हटाएं", + "Permission:Create": "सृजन करना", + "Permission:Documents": "दस्तावेज़", + "Menu:Documents": "दस्तावेज़", + "Menu:DocumentManagement": "दस्तावेज़", + "Menu:ProjectManagement": "परियोजनाओं", + "CreateANewProject": "नया प्रोजेक्ट बनाएं", + "Edit": "संपादित करें", + "Create": "सृजन करना", + "Pull": "खींचें", + "Projects": "परियोजनाओं", + "Name": "नाम", + "ShortName": "संक्षिप्त नाम", + "DocumentStoreType": "DocumentStoreType", + "Format": "प्रारूप", + "ShortNameInfoText": "अद्वितीय URL के लिए उपयोग किया जाएगा।", + "DisplayName:Name": "नाम", + "DisplayName:ShortName": "संक्षिप्त नाम", + "DisplayName:Format": "प्रारूप", + "DisplayName:DefaultDocumentName": "डिफ़ॉल्ट दस्तावेज़ नाम", + "DisplayName:NavigationDocumentName": "नेविगेशन दस्तावेज़ का नाम", + "DisplayName:MinimumVersion": "न्यूनतम संस्करण", + "DisplayName:MainWebsiteUrl": "मुख्य वेब साइट यूआरएल", + "DisplayName:LatestVersionBranchName": "नवीनतम संस्करण शाखा का नाम", + "DisplayName:GitHubRootUrl": "GitHub रूट URL", + "DisplayName:GitHubAccessToken": "गिटहब पहुंच टोकन", + "DisplayName:GitHubUserAgent": "GitHub उपयोगकर्ता एजेंट", + "DisplayName:GithubVersionProviderSource": "GitHub संस्करण प्रदाता स्रोत", + "DisplayName:VersionBranchPrefix": "संस्करण शाखा उपसर्ग", + "DisplayName:All": "सभी को खींचो", + "DisplayName:LanguageCode": "भाषा कोड", + "DisplayName:Version": "संस्करण", + "Documents": "दस्तावेज़", + "RemoveFromCache": "कैश से निकालें", + "Reindex": "अनुक्रमणः", + "ReindexCompleted": "रेनडेक्स पूरा किया", + "RemovedFromCache": "कैश से निकाला गया", + "RemoveFromCacheConfirmation": "क्या आप वाकई इस आइटम को कैश से निकालना चाहते हैं?", + "ReIndexDocumentConfirmation": "क्या आप वाकई इस आइटम को फिर से दिखाना चाहते हैं?", + "DeleteFromDatabase": "डेटाबेस से हटाएं", + "Deleted": "हटाए गए", + "Search": "खोज", + "StartDate": "आरंभ करने की तिथि", + "EndDate": "समाप्ति तिथि", + "CreationTime": "रचना समय", + "LastUpdateTime": "आखिरी अपडेट", + "LastSignificantUpdateTime": "अंतिम महत्वपूर्ण अद्यतन", + "Version": "संस्करण", + "LanguageCode": "भाषा कोड", + "FileName": "फ़ाइल का नाम", + "LastCachedTime": "कैश समय" + } +} \ No newline at end of file diff --git a/modules/docs/src/Volo.Docs.Admin.Application.Contracts/Volo/Docs/Admin/Localization/Resources/Docs/ApplicationContracts/it.json b/modules/docs/src/Volo.Docs.Admin.Application.Contracts/Volo/Docs/Admin/Localization/Resources/Docs/ApplicationContracts/it.json new file mode 100644 index 0000000000..f8c2e41bfc --- /dev/null +++ b/modules/docs/src/Volo.Docs.Admin.Application.Contracts/Volo/Docs/Admin/Localization/Resources/Docs/ApplicationContracts/it.json @@ -0,0 +1,59 @@ +{ + "culture": "it", + "texts": { + "Permission:DocumentManagement": "Gestione documenti", + "Permission:Projects": "Progetti", + "Permission:Edit": "modificare", + "Permission:Delete": "Elimina", + "Permission:Create": "Creare", + "Permission:Documents": "Documenti", + "Menu:Documents": "Documenti", + "Menu:DocumentManagement": "Documenti", + "Menu:ProjectManagement": "Progetti", + "CreateANewProject": "Crea nuovo progetto", + "Edit": "modificare", + "Create": "Creare", + "Pull": "Tirare", + "Projects": "Progetti", + "Name": "Nome", + "ShortName": "Nome corto", + "DocumentStoreType": "DocumentStoreType", + "Format": "Formato", + "ShortNameInfoText": "Verrà utilizzato per URL univoco.", + "DisplayName:Name": "Nome", + "DisplayName:ShortName": "Nome corto", + "DisplayName:Format": "Formato", + "DisplayName:DefaultDocumentName": "Nome documento predefinito", + "DisplayName:NavigationDocumentName": "Nome del documento di navigazione", + "DisplayName:MinimumVersion": "Versione minima", + "DisplayName:MainWebsiteUrl": "URL del sito web principale", + "DisplayName:LatestVersionBranchName": "Nome del ramo della versione più recente", + "DisplayName:GitHubRootUrl": "URL radice di GitHub", + "DisplayName:GitHubAccessToken": "Token di accesso GitHub", + "DisplayName:GitHubUserAgent": "Agente utente GitHub", + "DisplayName:GithubVersionProviderSource": "Origine del provider della versione di GitHub", + "DisplayName:VersionBranchPrefix": "Prefisso del ramo della versione", + "DisplayName:All": "Tira tutto", + "DisplayName:LanguageCode": "Codice della lingua", + "DisplayName:Version": "Versione", + "Documents": "Documenti", + "RemoveFromCache": "Rimuovi dalla cache", + "Reindex": "Reindicizza", + "ReindexCompleted": "Reindicizzazione completata", + "RemovedFromCache": "Rimosso dalla cache", + "RemoveFromCacheConfirmation": "Sei sicuro di voler rimuovere questo elemento dalla cache?", + "ReIndexDocumentConfirmation": "Sei sicuro di voler reindicizzare questo articolo?", + "DeleteFromDatabase": "Elimina dal database", + "Deleted": "Eliminato", + "Search": "Ricerca", + "StartDate": "Data d'inizio", + "EndDate": "Data di fine", + "CreationTime": "Tempo di creazione", + "LastUpdateTime": "Ultimo aggiornamento", + "LastSignificantUpdateTime": "Ultimo aggiornamento significativo", + "Version": "Versione", + "LanguageCode": "Codice della lingua", + "FileName": "Nome del file", + "LastCachedTime": "Tempo di cache" + } +} \ No newline at end of file diff --git a/modules/docs/src/Volo.Docs.Admin.Application/Volo/Docs/Admin/Documents/DocumentAdminAppService.cs b/modules/docs/src/Volo.Docs.Admin.Application/Volo/Docs/Admin/Documents/DocumentAdminAppService.cs index f72644065d..ed36c4dc0e 100644 --- a/modules/docs/src/Volo.Docs.Admin.Application/Volo/Docs/Admin/Documents/DocumentAdminAppService.cs +++ b/modules/docs/src/Volo.Docs.Admin.Application/Volo/Docs/Admin/Documents/DocumentAdminAppService.cs @@ -27,7 +27,7 @@ namespace Volo.Docs.Admin.Documents private readonly IDistributedCache _documentUpdateCache; private readonly IDistributedCache> _versionCache; private readonly IDistributedCache _languageCache; - private readonly IDocumentFullSearch _documentFullSearch; + private readonly IDocumentFullSearch _elasticSearchService; public DocumentAdminAppService(IProjectRepository projectRepository, IDocumentRepository documentRepository, @@ -35,7 +35,7 @@ namespace Volo.Docs.Admin.Documents IDistributedCache documentUpdateCache, IDistributedCache> versionCache, IDistributedCache languageCache, - IDocumentFullSearch documentFullSearch) + IDocumentFullSearch elasticSearchService) { _projectRepository = projectRepository; _documentRepository = documentRepository; @@ -43,7 +43,7 @@ namespace Volo.Docs.Admin.Documents _documentUpdateCache = documentUpdateCache; _versionCache = versionCache; _languageCache = languageCache; - _documentFullSearch = documentFullSearch; + _elasticSearchService = elasticSearchService; LocalizationResource = typeof(DocsResource); } @@ -210,9 +210,11 @@ namespace Volo.Docs.Admin.Documents public async Task ReindexAsync(Guid documentId) { - await _documentFullSearch.DeleteAsync(documentId); + _elasticSearchService.ValidateElasticSearchEnabled(); + + await _elasticSearchService.DeleteAsync(documentId); var document = await _documentRepository.GetAsync(documentId); - await _documentFullSearch.AddOrUpdateAsync(document); + await _elasticSearchService.AddOrUpdateAsync(document); } private async Task UpdateDocumentUpdateInfoCache(Document document) diff --git a/modules/docs/src/Volo.Docs.Admin.Application/Volo/Docs/Admin/Projects/ProjectAdminAppService.cs b/modules/docs/src/Volo.Docs.Admin.Application/Volo/Docs/Admin/Projects/ProjectAdminAppService.cs index bc663a0252..24605f1cc8 100644 --- a/modules/docs/src/Volo.Docs.Admin.Application/Volo/Docs/Admin/Projects/ProjectAdminAppService.cs +++ b/modules/docs/src/Volo.Docs.Admin.Application/Volo/Docs/Admin/Projects/ProjectAdminAppService.cs @@ -1,6 +1,5 @@ using System; using System.Collections.Generic; -using System.Linq; using System.Threading.Tasks; using Microsoft.AspNetCore.Authorization; using Volo.Abp.Application.Dtos; @@ -18,13 +17,13 @@ namespace Volo.Docs.Admin.Projects { private readonly IProjectRepository _projectRepository; private readonly IDocumentRepository _documentRepository; - private readonly IDocumentFullSearch _documentFullSearch; + private readonly IDocumentFullSearch _elasticSearchService; private readonly IGuidGenerator _guidGenerator; public ProjectAdminAppService( IProjectRepository projectRepository, IDocumentRepository documentRepository, - IDocumentFullSearch documentFullSearch, + IDocumentFullSearch elasticSearchService, IGuidGenerator guidGenerator) { ObjectMapperContext = typeof(DocsAdminApplicationModule); @@ -32,7 +31,7 @@ namespace Volo.Docs.Admin.Projects _projectRepository = projectRepository; _documentRepository = documentRepository; - _documentFullSearch = documentFullSearch; + _elasticSearchService = elasticSearchService; _guidGenerator = guidGenerator; } @@ -120,11 +119,21 @@ namespace Volo.Docs.Admin.Projects public async Task ReindexAsync(ReindexInput input) { - var project = await _projectRepository.GetAsync(input.ProjectId); + _elasticSearchService.ValidateElasticSearchEnabled(); - await _documentFullSearch.DeleteAllByProjectIdAsync(project.Id); + await ReindexProjectAsync(input.ProjectId); + } + + private async Task ReindexProjectAsync(Guid projectId) + { + var project = await _projectRepository.FindAsync(projectId); + if (project == null) + { + throw new Exception("Cannot find the project with the Id " + projectId); + } var docs = await _documentRepository.GetListByProjectId(project.Id); + await _elasticSearchService.DeleteAllByProjectIdAsync(project.Id); foreach (var doc in docs) { @@ -138,35 +147,18 @@ namespace Volo.Docs.Admin.Projects continue; } - await _documentFullSearch.AddOrUpdateAsync(doc); + await _elasticSearchService.AddOrUpdateAsync(doc); } } public async Task ReindexAllAsync() { - await _documentFullSearch.DeleteAllAsync(); - - var docs = await _documentRepository.GetListAsync(); + _elasticSearchService.ValidateElasticSearchEnabled(); var projects = await _projectRepository.GetListAsync(); - foreach (var doc in docs) + + foreach (var project in projects) { - var project = projects.FirstOrDefault(x => x.Id == doc.ProjectId); - if (project == null) - { - continue; - } - - if (doc.FileName == project.NavigationDocumentName) - { - continue; - } - - if (doc.FileName == project.ParametersDocumentName) - { - continue; - } - - await _documentFullSearch.AddOrUpdateAsync(doc); + await ReindexProjectAsync(project.Id); } } } diff --git a/modules/docs/src/Volo.Docs.Admin.Web/Navigation/DocsMenuContributor.cs b/modules/docs/src/Volo.Docs.Admin.Web/Navigation/DocsMenuContributor.cs index 644dd037c4..41eba37ced 100644 --- a/modules/docs/src/Volo.Docs.Admin.Web/Navigation/DocsMenuContributor.cs +++ b/modules/docs/src/Volo.Docs.Admin.Web/Navigation/DocsMenuContributor.cs @@ -3,6 +3,7 @@ using Microsoft.AspNetCore.Authorization; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Localization; using Volo.Abp.UI.Navigation; +using Volo.Abp.Authorization.Permissions; using Volo.Docs.Localization; namespace Volo.Docs.Admin.Navigation @@ -27,8 +28,8 @@ namespace Volo.Docs.Admin.Navigation administrationMenu.AddItem(rootMenuItem); - rootMenuItem.AddItem(new ApplicationMenuItem(DocsMenuNames.Projects, l["Menu:ProjectManagement"], "~/Docs/Admin/Projects", requiredPermissionName: DocsAdminPermissions.Projects.Default)); - rootMenuItem.AddItem(new ApplicationMenuItem(DocsMenuNames.Documents, l["Menu:DocumentManagement"], "~/Docs/Admin/Documents", requiredPermissionName: DocsAdminPermissions.Documents.Default)); + rootMenuItem.AddItem(new ApplicationMenuItem(DocsMenuNames.Projects, l["Menu:ProjectManagement"], "~/Docs/Admin/Projects").RequirePermissions(DocsAdminPermissions.Projects.Default)); + rootMenuItem.AddItem(new ApplicationMenuItem(DocsMenuNames.Documents, l["Menu:DocumentManagement"], "~/Docs/Admin/Documents").RequirePermissions(DocsAdminPermissions.Documents.Default)); return Task.CompletedTask; } diff --git a/modules/docs/src/Volo.Docs.Domain/Volo/Docs/Documents/FullSearch/Elastic/ElasticDocumentFullSearch.cs b/modules/docs/src/Volo.Docs.Domain/Volo/Docs/Documents/FullSearch/Elastic/ElasticDocumentFullSearch.cs index 7160ca405b..7a47cd7b45 100644 --- a/modules/docs/src/Volo.Docs.Domain/Volo/Docs/Documents/FullSearch/Elastic/ElasticDocumentFullSearch.cs +++ b/modules/docs/src/Volo.Docs.Domain/Volo/Docs/Documents/FullSearch/Elastic/ElasticDocumentFullSearch.cs @@ -56,8 +56,6 @@ namespace Volo.Docs.Documents.FullSearch.Elastic public virtual async Task AddOrUpdateAsync(Document document, CancellationToken cancellationToken = default) { - ValidateElasticSearchEnabled(); - var client = _clientProvider.GetClient(); var esDocument = new EsDocument @@ -71,15 +69,13 @@ namespace Volo.Docs.Documents.FullSearch.Elastic Version = NormalizeField(document.Version) }; - await client.IndexAsync(esDocument , x=>x.Index(_options.IndexName), cancellationToken); + await client.IndexAsync(esDocument, x => x.Index(_options.IndexName), cancellationToken); } public virtual async Task DeleteAsync(Guid id, CancellationToken cancellationToken = default) { - ValidateElasticSearchEnabled(); - HandleError(await _clientProvider.GetClient() - .DeleteAsync(DocumentPath.Id( NormalizeField(id)), x => x.Index(_options.IndexName), cancellationToken)); + .DeleteAsync(DocumentPath.Id(NormalizeField(id)), x => x.Index(_options.IndexName), cancellationToken)); } public virtual async Task DeleteAllAsync(CancellationToken cancellationToken = default) @@ -210,7 +206,7 @@ namespace Volo.Docs.Documents.FullSearch.Elastic } } - protected virtual void ValidateElasticSearchEnabled() + public virtual void ValidateElasticSearchEnabled() { if (!_options.Enable) { diff --git a/modules/docs/src/Volo.Docs.Domain/Volo/Docs/Documents/FullSearch/Elastic/IDocumentFullSearch.cs b/modules/docs/src/Volo.Docs.Domain/Volo/Docs/Documents/FullSearch/Elastic/IDocumentFullSearch.cs index e05c31bda3..c84df577b7 100644 --- a/modules/docs/src/Volo.Docs.Domain/Volo/Docs/Documents/FullSearch/Elastic/IDocumentFullSearch.cs +++ b/modules/docs/src/Volo.Docs.Domain/Volo/Docs/Documents/FullSearch/Elastic/IDocumentFullSearch.cs @@ -20,5 +20,7 @@ namespace Volo.Docs.Documents.FullSearch.Elastic Task> SearchAsync(string context, Guid projectId, string languageCode, string version, int? skipCount = null, int? maxResultCount = null, CancellationToken cancellationToken = default); + + void ValidateElasticSearchEnabled(); } } diff --git a/modules/docs/src/Volo.Docs.Domain/Volo/Docs/Localization/Domain/FR.json b/modules/docs/src/Volo.Docs.Domain/Volo/Docs/Localization/Domain/fr.json similarity index 97% rename from modules/docs/src/Volo.Docs.Domain/Volo/Docs/Localization/Domain/FR.json rename to modules/docs/src/Volo.Docs.Domain/Volo/Docs/Localization/Domain/fr.json index 19c778831d..8244a8d439 100644 --- a/modules/docs/src/Volo.Docs.Domain/Volo/Docs/Localization/Domain/FR.json +++ b/modules/docs/src/Volo.Docs.Domain/Volo/Docs/Localization/Domain/fr.json @@ -1,7 +1,7 @@ { "culture": "fr", "texts": { - "Documents": "Des documents", + "Documents": "Documents", "BackToWebsite": "Retour au site", "Contributors": "Contributeurs", "ShareOn": "Partager sur", @@ -19,7 +19,7 @@ "SuccessfullyReIndexAllProject": "Réindexation réussie pour tous les projets", "InThisDocument": "Dans ce document", "GoToTop": "Haut de la page", - "Projects": "Projets)", + "Projects": "Projet(s)", "NoProjectWarning": "Il n'y a pas encore de projets!", "DocumentNotFound": "Oups, le document demandé est introuvable!", "ProjectNotFound": "Oups, le projet demandé est introuvable!", diff --git a/modules/docs/src/Volo.Docs.Domain/Volo/Docs/Localization/Domain/hi.json b/modules/docs/src/Volo.Docs.Domain/Volo/Docs/Localization/Domain/hi.json new file mode 100644 index 0000000000..502561a6e1 --- /dev/null +++ b/modules/docs/src/Volo.Docs.Domain/Volo/Docs/Localization/Domain/hi.json @@ -0,0 +1,41 @@ +{ + "culture": "hi", + "texts": { + "Documents": "दस्तावेज़", + "BackToWebsite": "वेबसाइट पर वापस", + "Contributors": "योगदानकर्ताओं", + "ShareOn": "पर साझा करें", + "Version": "संस्करण", + "Edit": "संपादित करें", + "LastEditTime": "अंतिम संपादन", + "Delete": "हटाएं", + "ClearCache": "कैश को साफ़ करें", + "ClearCacheConfirmationMessage": "क्या आप प्रोजेक्ट \"{0}\" के लिए सभी कैश साफ़ करना सुनिश्चित कर रहे हैं", + "ReIndexAllProjects": "सभी परियोजनाओं को फिर से लिखना", + "ReIndexProject": "ReIndex परियोजना", + "ReIndexProjectConfirmationMessage": "क्या आप प्रोजेक्ट \"{0}\" के लिए निश्चित हैं", + "SuccessfullyReIndexProject": "प्रोजेक्ट \"{0}\" के लिए सफलतापूर्वक reindex", + "ReIndexAllProjectConfirmationMessage": "क्या आप सभी प्रोजेक्ट को फिर से बनाना सुनिश्चित कर रहे हैं?", + "SuccessfullyReIndexAllProject": "सभी प्रोजेक्ट्स के लिए सफलतापूर्वक रीइंडेक्स", + "InThisDocument": "इस दस्तावेज़ में", + "GoToTop": "ऊपर जाएँ", + "Projects": "परियोजना", + "NoProjectWarning": "अभी तक कोई प्रोजेक्ट नहीं हैं!", + "DocumentNotFound": "ओह, अनुरोधित दस्तावेज़ नहीं मिला!", + "ProjectNotFound": "उफ़, अनुरोधित प्रोजेक्ट नहीं मिला!", + "NavigationDocumentNotFound": "इस संस्करण में एक नेविगेशन दस्तावेज़ नहीं है!", + "DocumentNotFoundInSelectedLanguage": "जिस भाषा में आप चाहते थे वह दस्तावेज नहीं मिला। डिफ़ॉल्ट भाषा में दस्तावेज़ दिखाया गया है।", + "FilterTopics": "विषयों को फ़िल्टर करें", + "FullSearch": "दस्तावेजों में खोजें", + "Volo.Docs.Domain:010001": "लोचदार खोज सक्षम नहीं है।", + "MultipleVersionDocumentInfo": "इस दस्तावेज़ के कई संस्करण हैं। आपके लिए सबसे उपयुक्त विकल्प का चयन करें।", + "New": "नवीन व", + "Upd": "युपीडी", + "NewExplanation": "पिछले दो हफ्तों में बनाया गया।", + "UpdatedExplanation": "पिछले दो हफ्तों में अपडेट किया गया।", + "Volo.Docs.Domain:010002": "ShortName {ShortName} पहले से मौजूद है।", + "Preview": "पूर्व दर्शन", + "Search": "खोज", + "SearchResults": "खोज परिणाम" + } +} \ No newline at end of file diff --git a/modules/docs/src/Volo.Docs.Domain/Volo/Docs/Localization/Domain/it.json b/modules/docs/src/Volo.Docs.Domain/Volo/Docs/Localization/Domain/it.json new file mode 100644 index 0000000000..b66a7376a1 --- /dev/null +++ b/modules/docs/src/Volo.Docs.Domain/Volo/Docs/Localization/Domain/it.json @@ -0,0 +1,41 @@ +{ + "culture": "it", + "texts": { + "Documents": "Documenti", + "BackToWebsite": "Torna al sito web", + "Contributors": "Contributori", + "ShareOn": "Condividere su", + "Version": "Versione", + "Edit": "modificare", + "LastEditTime": "Ultima modifica", + "Delete": "Elimina", + "ClearCache": "Cancella cache", + "ClearCacheConfirmationMessage": "Sei sicuro di cancellare tutte le cache per il progetto \"{0}\"", + "ReIndexAllProjects": "ReIndex tutti i progetti", + "ReIndexProject": "Progetto ReIndex", + "ReIndexProjectConfirmationMessage": "Reindicizzare per il progetto \"{0}\"", + "SuccessfullyReIndexProject": "Reindicizzazione riuscita per il progetto \"{0}\"", + "ReIndexAllProjectConfirmationMessage": "Sei sicuro di reindicizzare tutto il progetto?", + "SuccessfullyReIndexAllProject": "Reindicizza con successo tutti i progetti", + "InThisDocument": "In questo documento", + "GoToTop": "Vai in alto", + "Projects": "Progetto (i)", + "NoProjectWarning": "Non ci sono ancora progetti!", + "DocumentNotFound": "Oops, il documento richiesto non è stato trovato!", + "ProjectNotFound": "Oops, il progetto richiesto non è stato trovato!", + "NavigationDocumentNotFound": "Questa versione non ha un documento di navigazione!", + "DocumentNotFoundInSelectedLanguage": "Il documento nella lingua desiderata non è stato trovato. Viene visualizzato il documento nella lingua predefinita.", + "FilterTopics": "Filtra gli argomenti", + "FullSearch": "Cerca nei documenti", + "Volo.Docs.Domain:010001": "La ricerca elastica non è abilitata.", + "MultipleVersionDocumentInfo": "Questo documento ha più versioni. Seleziona le opzioni più adatte a te.", + "New": "Nuovo", + "Upd": "Agg", + "NewExplanation": "Creato nelle ultime due settimane.", + "UpdatedExplanation": "Aggiornato nelle ultime due settimane.", + "Volo.Docs.Domain:010002": "ShortName {ShortName} esiste già.", + "Preview": "anteprima", + "Search": "Ricerca", + "SearchResults": "risultati di ricerca" + } +} \ No newline at end of file diff --git a/modules/docs/src/Volo.Docs.Web/Bundling/PrismjsScriptBundleContributorDocsExtension.cs b/modules/docs/src/Volo.Docs.Web/Bundling/PrismjsScriptBundleContributorDocsExtension.cs index 9406c2f6f2..9309234be7 100644 --- a/modules/docs/src/Volo.Docs.Web/Bundling/PrismjsScriptBundleContributorDocsExtension.cs +++ b/modules/docs/src/Volo.Docs.Web/Bundling/PrismjsScriptBundleContributorDocsExtension.cs @@ -5,14 +5,47 @@ namespace Volo.Docs.Bundling { public class PrismjsScriptBundleContributorDocsExtension : BundleContributor { + private static readonly string[] SupportedLanguages = new[] { + "csharp", + "json", + "aspnet", + "bash", + "css", + "css-extras", + "docker", + "javascript", + "less", + "markdown", + "nginx", + "powershell", + "regex", + "sass", + "scss", + "sql", + "typescript" + }; + public override void ConfigureBundle(BundleConfigurationContext context) + { + AddPlugins(context); + AddLanguages(context); + } + + private static void AddLanguages(IBundleConfigurationContext context) + { + const string componentsPath = "/libs/prismjs/components/prism-{0}.js"; + foreach (var language in SupportedLanguages) + { + context.Files.AddIfNotContains(string.Format(componentsPath, language)); + } + } + + private static void AddPlugins(IBundleConfigurationContext context) { context.Files.AddIfNotContains("/libs/prismjs/plugins/toolbar/prism-toolbar.js"); context.Files.AddIfNotContains("/libs/prismjs/plugins/show-language/prism-show-language.js"); context.Files.AddIfNotContains("/libs/prismjs/plugins/copy-to-clipboard/prism-copy-to-clipboard.js"); context.Files.AddIfNotContains("/libs/prismjs/plugins/line-highlight/prism-line-highlight.js"); - context.Files.AddIfNotContains("/libs/prismjs/components/prism-csharp.js"); - context.Files.AddIfNotContains("/libs/prismjs/components/prism-json.js"); } } } diff --git a/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain.Shared/Volo/Abp/FeatureManagement/Localization/Domain/hi.json b/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain.Shared/Volo/Abp/FeatureManagement/Localization/Domain/hi.json new file mode 100644 index 0000000000..51fe35a788 --- /dev/null +++ b/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain.Shared/Volo/Abp/FeatureManagement/Localization/Domain/hi.json @@ -0,0 +1,10 @@ +{ + "culture": "hi", + "texts": { + "Features": "विशेषताएं", + "NoFeatureFoundMessage": "कोई भी उपलब्ध सुविधा नहीं है।", + "Permission:FeatureManagement": "सुविधा प्रबंधन", + "Permission:FeatureManagement.ManageHostFeatures": "होस्ट सुविधाएँ प्रबंधित करें", + "Volo.Abp.FeatureManagement:InvalidFeatureValue": "{0} सुविधा मान मान्य नहीं है!" + } +} \ No newline at end of file diff --git a/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain.Shared/Volo/Abp/FeatureManagement/Localization/Domain/it.json b/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain.Shared/Volo/Abp/FeatureManagement/Localization/Domain/it.json new file mode 100644 index 0000000000..0d975f6ed5 --- /dev/null +++ b/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain.Shared/Volo/Abp/FeatureManagement/Localization/Domain/it.json @@ -0,0 +1,10 @@ +{ + "culture": "it", + "texts": { + "Features": "Caratteristiche", + "NoFeatureFoundMessage": "Non ci sono funzioni disponibili.", + "Permission:FeatureManagement": "Gestione delle funzionalità", + "Permission:FeatureManagement.ManageHostFeatures": "Gestisci le funzionalità dell'host", + "Volo.Abp.FeatureManagement:InvalidFeatureValue": "Il valore dell'elemento {0} non è valido!" + } +} \ No newline at end of file diff --git a/modules/identity/Volo.Abp.Identity.abpmdl.json b/modules/identity/Volo.Abp.Identity.abpmdl.json index 91c285965d..f58988ab30 100644 --- a/modules/identity/Volo.Abp.Identity.abpmdl.json +++ b/modules/identity/Volo.Abp.Identity.abpmdl.json @@ -1,150 +1,90 @@ { "folders": { - "src": {}, - "test": {} - }, - "imports": { - "Volo.Abp.Users": { - "path": "../users/Volo.Abp.Users.abpmdl.json" - }, - "Volo.Abp.PermissionManagement": { - "path": "../permission-management/Volo.Abp.PermissionManagement.abpmdl.json" + "items": { + "src": {}, + "test": {} } }, "packages": { "Volo.Abp.Identity.Domain.Shared": { - "path": "src/Volo.Abp.Identity.Domain.Shared/Volo.Abp.Identity.Domain.Shared.csproj", - "folder": "src", - "includes": { - "lib.domain.shared": {} - } + "path": "src/Volo.Abp.Identity.Domain.Shared/Volo.Abp.Identity.Domain.Shared.abppkg.json", + "folder": "src" }, "Volo.Abp.Identity.Domain": { - "path": "src/Volo.Abp.Identity.Domain/Volo.Abp.Identity.Domain.csproj", - "folder": "src", - "includes": { - "lib.domain": {} - } + "path": "src/Volo.Abp.Identity.Domain/Volo.Abp.Identity.Domain.abppkg.json", + "folder": "src" }, "Volo.Abp.Identity.Application.Contracts": { - "path": "src/Volo.Abp.Identity.Application.Contracts/Volo.Abp.Identity.Application.Contracts.csproj", - "folder": "src", - "includes": { - "lib.application.contracts": {} - } + "path": "src/Volo.Abp.Identity.Application.Contracts/Volo.Abp.Identity.Application.Contracts.abppkg.json", + "folder": "src" }, "Volo.Abp.Identity.Application": { - "path": "src/Volo.Abp.Identity.Application/Volo.Abp.Identity.Application.csproj", - "folder": "src", - "includes": { - "lib.application": {} - } + "path": "src/Volo.Abp.Identity.Application/Volo.Abp.Identity.Application.abppkg.json", + "folder": "src" }, "Volo.Abp.Identity.EntityFrameworkCore": { - "path": "src/Volo.Abp.Identity.EntityFrameworkCore/Volo.Abp.Identity.EntityFrameworkCore.csproj", - "folder": "src", - "includes": { - "lib.ef": {} - } - }, - "Volo.Abp.Identity.MongoDB": { - "path": "src/Volo.Abp.Identity.MongoDB/Volo.Abp.Identity.MongoDB.csproj", - "folder": "src", - "includes": { - "lib.mongodb": {} - } - }, - "Volo.Abp.Identity.AspNetCore": { - "path": "src/Volo.Abp.Identity.AspNetCore/Volo.Abp.Identity.AspNetCore.csproj", + "path": "src/Volo.Abp.Identity.EntityFrameworkCore/Volo.Abp.Identity.EntityFrameworkCore.abppkg.json", "folder": "src" }, "Volo.Abp.Identity.HttpApi": { - "path": "src/Volo.Abp.Identity.HttpApi/Volo.Abp.Identity.HttpApi.csproj", - "folder": "src", - "includes": { - "lib.http-api": {} - } + "path": "src/Volo.Abp.Identity.HttpApi/Volo.Abp.Identity.HttpApi.abppkg.json", + "folder": "src" }, "Volo.Abp.Identity.HttpApi.Client": { - "path": "src/Volo.Abp.Identity.HttpApi.Client/Volo.Abp.Identity.HttpApi.Client.csproj", - "folder": "src", - "includes": { - "lib.http-api-client": {} - } + "path": "src/Volo.Abp.Identity.HttpApi.Client/Volo.Abp.Identity.HttpApi.Client.abppkg.json", + "folder": "src" }, "Volo.Abp.Identity.Web": { - "path": "src/Volo.Abp.Identity.Web/Volo.Abp.Identity.Web.csproj", - "folder": "src", - "includes": { - "lib.ui.mvc": {} - } + "path": "src/Volo.Abp.Identity.Web/Volo.Abp.Identity.Web.abppkg.json", + "folder": "src" }, - "Volo.Abp.Identity.Blazor": { - "path": "src/Volo.Abp.Identity.Blazor/Volo.Abp.Identity.Blazor.csproj", - "folder": "src", - "includes": { - "lib.ui.blazor": {} - } + "Volo.Abp.Identity.Application.Tests": { + "path": "test/Volo.Abp.Identity.Application.Tests/Volo.Abp.Identity.Application.Tests.abppkg.json", + "folder": "test" }, - "Volo.Abp.Identity.Blazor.Server": { - "path": "src/Volo.Abp.Identity.Blazor.Server/Volo.Abp.Identity.Blazor.Server.csproj", - "folder": "src", - "includes": { - "lib.ui.blazor-server": {} - } + "Volo.Abp.Identity.MongoDB": { + "path": "src/Volo.Abp.Identity.MongoDB/Volo.Abp.Identity.MongoDB.abppkg.json", + "folder": "src" }, - "Volo.Abp.Identity.Blazor.WebAssembly": { - "path": "src/Volo.Abp.Identity.Blazor.WebAssembly/Volo.Abp.Identity.Blazor.WebAssembly.csproj", - "folder": "src", - "includes": { - "lib.ui.blazor-wasm": {} - } + "Volo.Abp.Identity.MongoDB.Tests": { + "path": "test/Volo.Abp.Identity.MongoDB.Tests/Volo.Abp.Identity.MongoDB.Tests.abppkg.json", + "folder": "test" }, - "Volo.Abp.PermissionManagement.Domain.Identity": { - "path": "src/Volo.Abp.PermissionManagement.Domain.Identity/Volo.Abp.PermissionManagement.Domain.Identity.csproj", - "folder": "src" + "Volo.Abp.Identity.EntityFrameworkCore.Tests": { + "path": "test/Volo.Abp.Identity.EntityFrameworkCore.Tests/Volo.Abp.Identity.EntityFrameworkCore.Tests.abppkg.json", + "folder": "test" }, "Volo.Abp.Identity.TestBase": { - "path": "test/Volo.Abp.Identity.TestBase/Volo.Abp.Identity.TestBase.csproj", - "folder": "test", - "includes": { - "lib.test": {} - } + "path": "test/Volo.Abp.Identity.TestBase/Volo.Abp.Identity.TestBase.abppkg.json", + "folder": "test" }, "Volo.Abp.Identity.Domain.Tests": { - "path": "test/Volo.Abp.Identity.Domain.Tests/Volo.Abp.Identity.Domain.Tests.csproj", - "folder": "test", - "includes": { - "lib.test": {} - } - }, - "Volo.Abp.Identity.EntityFrameworkCore.Tests": { - "path": "test/Volo.Abp.Identity.EntityFrameworkCore.Tests/Volo.Abp.Identity.EntityFrameworkCore.Tests.csproj", - "folder": "test", - "includes": { - "lib.test": {} - } + "path": "test/Volo.Abp.Identity.Domain.Tests/Volo.Abp.Identity.Domain.Tests.abppkg.json", + "folder": "test" }, - "Volo.Abp.Identity.MongoDB.Tests": { - "path": "test/Volo.Abp.Identity.MongoDB.Tests/Volo.Abp.Identity.MongoDB.Tests.csproj", - "folder": "test", - "includes": { - "lib.test": {} - } + "Volo.Abp.Identity.AspNetCore": { + "path": "src/Volo.Abp.Identity.AspNetCore/Volo.Abp.Identity.AspNetCore.abppkg.json", + "folder": "src" }, - "Volo.Abp.Identity.Application.Tests": { - "path": "test/Volo.Abp.Identity.Application.Tests/Volo.Abp.Identity.Application.Tests.csproj", - "folder": "test", - "includes": { - "lib.test": {} - } + "Volo.Abp.PermissionManagement.Domain.Identity": { + "path": "src/Volo.Abp.PermissionManagement.Domain.Identity/Volo.Abp.PermissionManagement.Domain.Identity.abppkg.json", + "folder": "src" }, "Volo.Abp.Identity.AspNetCore.Tests": { - "path": "test/Volo.Abp.Identity.AspNetCore.Tests/Volo.Abp.Identity.AspNetCore.Tests.csproj", - "folder": "test", - "includes": { - "lib.test": {} - } + "path": "test/Volo.Abp.Identity.AspNetCore.Tests/Volo.Abp.Identity.AspNetCore.Tests.abppkg.json", + "folder": "test" + }, + "Volo.Abp.Identity.Blazor": { + "path": "src/Volo.Abp.Identity.Blazor/Volo.Abp.Identity.Blazor.abppkg.json", + "folder": "src" + }, + "Volo.Abp.Identity.Blazor.Server": { + "path": "src/Volo.Abp.Identity.Blazor.Server/Volo.Abp.Identity.Blazor.Server.abppkg.json", + "folder": "src" + }, + "Volo.Abp.Identity.Blazor.WebAssembly": { + "path": "src/Volo.Abp.Identity.Blazor.WebAssembly/Volo.Abp.Identity.Blazor.WebAssembly.abppkg.json", + "folder": "src" } } } \ No newline at end of file diff --git a/modules/identity/src/Volo.Abp.Identity.Application.Contracts/Volo.Abp.Identity.Application.Contracts.abppkg.json b/modules/identity/src/Volo.Abp.Identity.Application.Contracts/Volo.Abp.Identity.Application.Contracts.abppkg.json new file mode 100644 index 0000000000..49032794e2 --- /dev/null +++ b/modules/identity/src/Volo.Abp.Identity.Application.Contracts/Volo.Abp.Identity.Application.Contracts.abppkg.json @@ -0,0 +1,3 @@ +{ + "role": "lib.application-contracts" +} \ No newline at end of file diff --git a/modules/identity/src/Volo.Abp.Identity.Application/Volo.Abp.Identity.Application.abppkg.json b/modules/identity/src/Volo.Abp.Identity.Application/Volo.Abp.Identity.Application.abppkg.json new file mode 100644 index 0000000000..412567ac33 --- /dev/null +++ b/modules/identity/src/Volo.Abp.Identity.Application/Volo.Abp.Identity.Application.abppkg.json @@ -0,0 +1,3 @@ +{ + "role": "lib.application" +} \ No newline at end of file diff --git a/modules/identity/src/Volo.Abp.Identity.AspNetCore/Volo.Abp.Identity.AspNetCore.abppkg.json b/modules/identity/src/Volo.Abp.Identity.AspNetCore/Volo.Abp.Identity.AspNetCore.abppkg.json new file mode 100644 index 0000000000..9e26dfeeb6 --- /dev/null +++ b/modules/identity/src/Volo.Abp.Identity.AspNetCore/Volo.Abp.Identity.AspNetCore.abppkg.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/modules/identity/src/Volo.Abp.Identity.AspNetCore/Volo/Abp/Identity/AspNetCore/AbpSecurityStampValidator.cs b/modules/identity/src/Volo.Abp.Identity.AspNetCore/Volo/Abp/Identity/AspNetCore/AbpSecurityStampValidator.cs index 1dcc624a47..8ae543bed2 100644 --- a/modules/identity/src/Volo.Abp.Identity.AspNetCore/Volo/Abp/Identity/AspNetCore/AbpSecurityStampValidator.cs +++ b/modules/identity/src/Volo.Abp.Identity.AspNetCore/Volo/Abp/Identity/AspNetCore/AbpSecurityStampValidator.cs @@ -1,4 +1,5 @@ -using System.Threading.Tasks; +using System; +using System.Threading.Tasks; using Microsoft.AspNetCore.Authentication; using Microsoft.AspNetCore.Authentication.Cookies; using Microsoft.AspNetCore.Identity; @@ -34,7 +35,16 @@ namespace Volo.Abp.Identity.AspNetCore [UnitOfWork] public override async Task ValidateAsync(CookieValidatePrincipalContext context) { - var tenant = await TenantConfigurationProvider.GetAsync(saveResolveResult: false); + TenantConfiguration tenant = null; + try + { + tenant = await TenantConfigurationProvider.GetAsync(saveResolveResult: false); + } + catch (Exception e) + { + Logger.LogException(e); + } + using (CurrentTenant.Change(tenant?.Id, tenant?.Name)) { await base.ValidateAsync(context); diff --git a/modules/identity/src/Volo.Abp.Identity.Blazor.Server/Volo.Abp.Identity.Blazor.Server.abppkg.json b/modules/identity/src/Volo.Abp.Identity.Blazor.Server/Volo.Abp.Identity.Blazor.Server.abppkg.json new file mode 100644 index 0000000000..ef40d81585 --- /dev/null +++ b/modules/identity/src/Volo.Abp.Identity.Blazor.Server/Volo.Abp.Identity.Blazor.Server.abppkg.json @@ -0,0 +1,3 @@ +{ + "role": "lib.blazor-server" +} \ No newline at end of file diff --git a/modules/identity/src/Volo.Abp.Identity.Blazor.WebAssembly/Volo.Abp.Identity.Blazor.WebAssembly.abppkg.json b/modules/identity/src/Volo.Abp.Identity.Blazor.WebAssembly/Volo.Abp.Identity.Blazor.WebAssembly.abppkg.json new file mode 100644 index 0000000000..471ef5e067 --- /dev/null +++ b/modules/identity/src/Volo.Abp.Identity.Blazor.WebAssembly/Volo.Abp.Identity.Blazor.WebAssembly.abppkg.json @@ -0,0 +1,3 @@ +{ + "role": "lib.blazor-wasm" +} \ No newline at end of file diff --git a/modules/identity/src/Volo.Abp.Identity.Blazor/AbpIdentityWebMainMenuContributor.cs b/modules/identity/src/Volo.Abp.Identity.Blazor/AbpIdentityWebMainMenuContributor.cs index 9b75491d0b..fafa8eac9b 100644 --- a/modules/identity/src/Volo.Abp.Identity.Blazor/AbpIdentityWebMainMenuContributor.cs +++ b/modules/identity/src/Volo.Abp.Identity.Blazor/AbpIdentityWebMainMenuContributor.cs @@ -1,6 +1,7 @@ using System.Threading.Tasks; using Volo.Abp.Identity.Localization; using Volo.Abp.UI.Navigation; +using Volo.Abp.Authorization.Permissions; namespace Volo.Abp.Identity.Blazor { @@ -24,15 +25,12 @@ namespace Volo.Abp.Identity.Blazor identityMenuItem.AddItem(new ApplicationMenuItem( IdentityMenuNames.Roles, l["Roles"], - url: "~/identity/roles", - requiredPermissionName: IdentityPermissions.Roles.Default)); - + url: "~/identity/roles").RequirePermissions(IdentityPermissions.Roles.Default)); identityMenuItem.AddItem(new ApplicationMenuItem( IdentityMenuNames.Users, l["Users"], - url: "~/identity/users", - requiredPermissionName: IdentityPermissions.Users.Default)); + url: "~/identity/users").RequirePermissions(IdentityPermissions.Users.Default)); return Task.CompletedTask; } diff --git a/modules/identity/src/Volo.Abp.Identity.Blazor/Volo.Abp.Identity.Blazor.abppkg.json b/modules/identity/src/Volo.Abp.Identity.Blazor/Volo.Abp.Identity.Blazor.abppkg.json new file mode 100644 index 0000000000..19c29b7b8b --- /dev/null +++ b/modules/identity/src/Volo.Abp.Identity.Blazor/Volo.Abp.Identity.Blazor.abppkg.json @@ -0,0 +1,3 @@ +{ + "role": "lib.blazor" +} \ No newline at end of file diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo.Abp.Identity.Domain.Shared.abppkg.json b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo.Abp.Identity.Domain.Shared.abppkg.json new file mode 100644 index 0000000000..8b3de05f76 --- /dev/null +++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo.Abp.Identity.Domain.Shared.abppkg.json @@ -0,0 +1,3 @@ +{ + "role": "lib.domain-shared" +} \ No newline at end of file diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/es.json b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/es.json index dfc5193e62..20cec1eded 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/es.json +++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/es.json @@ -16,8 +16,8 @@ "PersonalInfo": "Mi perfil", "PersonalSettings": "Configuración personal", "UserDeletionConfirmationMessage": "El usuario '{0}' será eliminado. ¿Quieres continuar?", - "RoleDeletionConfirmationMessage": "El role '{0}' será eliminado. ¿Quieres continuar? ", - "DisplayName:RoleName": "Nombre de Role", + "RoleDeletionConfirmationMessage": "El rol '{0}' será eliminado. ¿Quieres continuar? ", + "DisplayName:RoleName": "Nombre de rol", "DisplayName:UserName": "Nombre de usuario", "DisplayName:Name": "Nombre", "DisplayName:Surname": "Apellido", @@ -26,8 +26,8 @@ "DisplayName:PhoneNumber": "Número de teléfono", "DisplayName:TwoFactorEnabled": "Autenticación en dos pasos", "DisplayName:LockoutEnabled": "Bloquear la cuenta después de intentos de inicio de sesión fallidos", - "NewRole": "Nuevo role", - "RoleName": "Nombre de role", + "NewRole": "Nuevo rol", + "RoleName": "Nombre de rol", "CreationTime": "Fecha de creación", "Permissions": "Permisos", "DisplayName:CurrentPassword": "Contraseña actual", @@ -38,12 +38,12 @@ "Volo.Abp.Identity:DefaultError": "Error desconocido.", "Volo.Abp.Identity:ConcurrencyFailure": "Fallo de concurrencia optimista", "Volo.Abp.Identity:DuplicateEmail": "E-mail '{0}' está en uso.", - "Volo.Abp.Identity:DuplicateRoleName": "Nombre de role '{0}' está en uso.", - "Volo.Abp.Identity:DuplicateUserName": "Nombre de usuario '{0}' está en uso.", + "Volo.Abp.Identity:DuplicateRoleName": "El nombre de rol '{0}' ya está en uso.", + "Volo.Abp.Identity:DuplicateUserName": "El nombre de usuario '{0}' ya está en uso.", "Volo.Abp.Identity:InvalidEmail": "E-mail '{0}' no es válido.", "Volo.Abp.Identity:InvalidPasswordHasherCompatibilityMode": "El PasswordHasherCompatibilityMode proporcionado no es válido.", "Volo.Abp.Identity:InvalidPasswordHasherIterationCount": "La cuenta iterativa debe ser una entero positivo.", - "Volo.Abp.Identity:InvalidRoleName": "El nombre de role '{0}' no es válido.", + "Volo.Abp.Identity:InvalidRoleName": "El nombre de rol '{0}' no es válido.", "Volo.Abp.Identity:InvalidToken": "token no válido", "Volo.Abp.Identity:InvalidUserName": "Nombre de usuario '{0}' no es válido. Sólo puede contener letras o dígitos", "Volo.Abp.Identity:LoginAlreadyAssociated": "Usuario con este inicio de sesión en uso.", @@ -53,7 +53,7 @@ "Volo.Abp.Identity:PasswordRequiresNonAlphanumeric": "Contraseñas deben tener al menos un carácter no alfanumérico", "Volo.Abp.Identity:PasswordRequiresUpper": "Contraseñas deben tener al menos un carácter en mayúsculas ('A'-'Z').", "Volo.Abp.Identity:PasswordTooShort": "Contraseñas deben tener al menos {0} caracteres", - "Volo.Abp.Identity:RoleNotFound": "El role {0} no existe.", + "Volo.Abp.Identity:RoleNotFound": "El rol {0} no existe.", "Volo.Abp.Identity:UserAlreadyHasPassword": "El usuario tiene la contraseña establecida", "Volo.Abp.Identity:UserAlreadyInRole": "El usuario ya tiene asignado el rol '{0}'´.", "Volo.Abp.Identity:UserLockedOut": "El usuario está bloqueado.", @@ -65,8 +65,8 @@ "Volo.Abp.Identity:010002": "No puedes establecer más de {MaxUserMembershipCount} unidades organizativas para un usuario!", "Volo.Abp.Identity:010003": "No puedes cambiar la contraseña de un usuario que inicio sesión desde un servicio externo!", "Volo.Abp.Identity:010004": "Hay una unidad organizativa con nombre {0}. Dos unidades con el mismo nombre no pueden ser creadas en el mismo nivel.", - "Volo.Abp.Identity:010005": "Roles estáticos no pueden ser renombrados.", - "Volo.Abp.Identity:010006": "Roles estáticos no pueden ser borrados.", + "Volo.Abp.Identity:010005": "Los roles estáticos no pueden ser renombrados.", + "Volo.Abp.Identity:010006": "Los roles estáticos no pueden ser borrados.", "Volo.Abp.Identity:010007": "No puedes cambiar tu configuración de autentificación de dos pasos.", "Volo.Abp.Identity:010008": "No está permitido cambiar la configuración de autenticación de dos pasos.", "Identity.OrganizationUnit.MaxUserMembershipCount": "Número máximo de unidades organizativas por usuario", diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/hi.json b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/hi.json new file mode 100644 index 0000000000..a0b4e70c15 --- /dev/null +++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/hi.json @@ -0,0 +1,110 @@ +{ + "culture": "hi", + "texts": { + "Menu:IdentityManagement": "पहचान प्रबंधन", + "Users": "उपयोगकर्ताओं", + "NewUser": "नया उपयोगकर्ता", + "UserName": "उपयोगकर्ता नाम", + "EmailAddress": "ईमेल पता", + "PhoneNumber": "फ़ोन नंबर", + "UserInformations": "यूजर जानकारी", + "DisplayName:IsDefault": "चूक", + "DisplayName:IsStatic": "स्थिर", + "DisplayName:IsPublic": "सह लोक", + "Roles": "भूमिकाएँ", + "Password": "कुंजिका", + "PersonalInfo": "मेरी प्रोफाइल", + "PersonalSettings": "व्यक्तिगत सेटिंग", + "UserDeletionConfirmationMessage": "उपयोगकर्ता '{0}' हटा दिया जाएगा। क्या आप इसकी पुष्टि करते हैं?", + "RoleDeletionConfirmationMessage": "भूमिका '{0}' हटा दी जाएगी। क्या आप इसकी पुष्टि करते हैं?", + "DisplayName:RoleName": "भूमिका का नाम", + "DisplayName:UserName": "उपयोगकर्ता नाम", + "DisplayName:Name": "नाम", + "DisplayName:Surname": "उपनाम", + "DisplayName:Password": "कुंजिका", + "DisplayName:Email": "ईमेल पता", + "DisplayName:PhoneNumber": "फ़ोन नंबर", + "DisplayName:TwoFactorEnabled": "दो कारक सत्यापन", + "DisplayName:LockoutEnabled": "असफल लॉगिन प्रयासों के बाद लॉक खाता", + "NewRole": "नयी भूमिका", + "RoleName": "भूमिका का नाम", + "CreationTime": "रचना समय", + "Permissions": "अनुमतियां", + "DisplayName:CurrentPassword": "वर्तमान पासवर्ड", + "DisplayName:NewPassword": "नया पासवर्ड", + "DisplayName:NewPasswordConfirm": "नए पासवर्ड की पुष्टि करें", + "PasswordChangedMessage": "तुम्हारा पासवर्ड सफलतापूर्वक बदल दिया गया है।", + "PersonalSettingsSavedMessage": "आपकी व्यक्तिगत सेटिंग्स सफलतापूर्वक सहेज ली गई हैं।", + "Volo.Abp.Identity:DefaultError": "एक अज्ञात विफलता हुई है।", + "Volo.Abp.Identity:ConcurrencyFailure": "आशावादी संगरोध विफलता, ऑब्जेक्ट संशोधित किया गया है।", + "Volo.Abp.Identity:DuplicateEmail": "ईमेल '{0}' पहले से ही लिया गया है।", + "Volo.Abp.Identity:DuplicateRoleName": "भूमिका नाम '{0}' पहले से ही लिया गया है।", + "Volo.Abp.Identity:DuplicateUserName": "उपयोगकर्ता नाम '{0}' पहले से ही लिया गया है।", + "Volo.Abp.Identity:InvalidEmail": "ईमेल '{0}' अमान्य है।", + "Volo.Abp.Identity:InvalidPasswordHasherCompatibilityMode": "प्रदान किया गया PasswordHasherCompatibilityMode अमान्य है।", + "Volo.Abp.Identity:InvalidPasswordHasherIterationCount": "चलना गणना एक सकारात्मक पूर्णांक होना चाहिए।", + "Volo.Abp.Identity:InvalidRoleName": "भूमिका नाम '{0}' अमान्य है।", + "Volo.Abp.Identity:InvalidToken": "अमान्य टोकन।", + "Volo.Abp.Identity:InvalidUserName": "उपयोगकर्ता नाम '{0}' अमान्य है, इसमें केवल अक्षर या अंक हो सकते हैं।", + "Volo.Abp.Identity:LoginAlreadyAssociated": "इस लॉगिन वाला उपयोगकर्ता पहले से मौजूद है।", + "Volo.Abp.Identity:PasswordMismatch": "गलत पासवर्ड।", + "Volo.Abp.Identity:PasswordRequiresDigit": "पासवर्ड में कम से कम एक अंक ('0' - '9') होना चाहिए।", + "Volo.Abp.Identity:PasswordRequiresLower": "पासवर्ड में कम से कम एक लोअरकेस ('a' - 'z') होना चाहिए।", + "Volo.Abp.Identity:PasswordRequiresNonAlphanumeric": "पासवर्ड में कम से कम एक गैर अल्फ़ान्यूमेरिक वर्ण होना चाहिए।", + "Volo.Abp.Identity:PasswordRequiresUpper": "पासवर्ड में कम से कम एक अपरकेस ('ए' - 'जेड') होना चाहिए।", + "Volo.Abp.Identity:PasswordTooShort": "पासवर्ड कम से कम {0} वर्ण का होना चाहिए।", + "Volo.Abp.Identity:RoleNotFound": "भूमिका {0} मौजूद नहीं है।", + "Volo.Abp.Identity:UserAlreadyHasPassword": "उपयोगकर्ता के पास पहले से ही एक पासवर्ड सेट है।", + "Volo.Abp.Identity:UserAlreadyInRole": "उपयोगकर्ता पहले से ही '{0}' की भूमिका में है।", + "Volo.Abp.Identity:UserLockedOut": "उपयोगकर्ता लॉक हो गया है।", + "Volo.Abp.Identity:UserLockoutNotEnabled": "इस उपयोगकर्ता के लिए लॉकआउट सक्षम नहीं है।", + "Volo.Abp.Identity:UserNameNotFound": "उपयोगकर्ता {0} मौजूद नहीं है।", + "Volo.Abp.Identity:UserNotInRole": "उपयोगकर्ता भूमिका '{0}' में नहीं है।", + "Volo.Abp.Identity:PasswordConfirmationFailed": "पासवर्ड पुष्टि पासवर्ड से मेल नहीं खाता है।", + "Volo.Abp.Identity:010001": "आप अपना स्वयं का खाता नहीं हटा सकते हैं!", + "Volo.Abp.Identity:010002": "उपयोगकर्ता के लिए {MaxUserMembershipCount} संगठन इकाई से अधिक सेट नहीं किया जा सकता है!", + "Volo.Abp.Identity:010003": "उपयोगकर्ता में बाहरी लॉग इन का पासवर्ड नहीं बदल सकता है!", + "Volo.Abp.Identity:010004": "पहले से ही एक संगठन इकाई है जिसका नाम {0} है। समान नाम वाली दो इकाइयाँ समान स्तर में नहीं बनाई जा सकती हैं।", + "Volo.Abp.Identity:010005": "स्थैतिक भूमिकाओं का नाम नहीं बदला जा सकता है।", + "Volo.Abp.Identity:010006": "स्टेटिक भूमिकाओं को हटाया नहीं जा सकता।", + "Volo.Abp.Identity:010007": "आप अपनी दो कारक सेटिंग नहीं बदल सकते।", + "Volo.Abp.Identity:010008": "इसे दो कारक सेटिंग बदलने की अनुमति नहीं है।", + "Identity.OrganizationUnit.MaxUserMembershipCount": "उपयोगकर्ता के लिए अधिकतम अनुमत संगठन इकाई सदस्यता गणना", + "Permission:IdentityManagement": "पहचान प्रबंधन", + "Permission:RoleManagement": "भूमिका प्रबंधन", + "Permission:Create": "सृजन करना", + "Permission:Edit": "संपादित करें", + "Permission:Delete": "हटाएं", + "Permission:ChangePermissions": "अनुमतियाँ बदलें", + "Permission:UserManagement": "उपयोगकर्ता प्रबंधन", + "Permission:UserLookup": "उपयोगकर्ता की खोज", + "DisplayName:Abp.Identity.Password.RequiredLength": "आवश्यक लंबाई", + "DisplayName:Abp.Identity.Password.RequiredUniqueChars": "आवश्यक अद्वितीय वर्ण संख्या", + "DisplayName:Abp.Identity.Password.RequireNonAlphanumeric": "गैर-अल्फ़ान्यूमेरिक वर्ण की आवश्यकता है", + "DisplayName:Abp.Identity.Password.RequireLowercase": "आवश्यक निचला मामला चरित्र", + "DisplayName:Abp.Identity.Password.RequireUppercase": "आवश्यक ऊपरी मामला चरित्र", + "DisplayName:Abp.Identity.Password.RequireDigit": "आवश्यक अंक", + "DisplayName:Abp.Identity.Lockout.AllowedForNewUsers": "नए उपयोगकर्ताओं के लिए सक्षम है", + "DisplayName:Abp.Identity.Lockout.LockoutDuration": "तालाबंदी अवधि (सेकंड)", + "DisplayName:Abp.Identity.Lockout.MaxFailedAccessAttempts": "अधिकतम पहुँच प्रयास विफल", + "DisplayName:Abp.Identity.SignIn.RequireConfirmedEmail": "पुष्टिकरण ईमेल की आवश्यकता है", + "DisplayName:Abp.Identity.SignIn.EnablePhoneNumberConfirmation": "उपयोगकर्ताओं को अपने फ़ोन नंबर की पुष्टि करने की अनुमति दें", + "DisplayName:Abp.Identity.SignIn.RequireConfirmedPhoneNumber": "पुष्टि किए गए फ़ोन नंबर की आवश्यकता है", + "DisplayName:Abp.Identity.User.IsUserNameUpdateEnabled": "उपयोगकर्ताओं को अपने उपयोगकर्ता नाम बदलने की अनुमति दें", + "DisplayName:Abp.Identity.User.IsEmailUpdateEnabled": "उपयोगकर्ताओं को अपने ईमेल पते बदलने की अनुमति दें", + "Description:Abp.Identity.Password.RequiredLength": "एक पासवर्ड की लंबाई न्यूनतम होनी चाहिए।", + "Description:Abp.Identity.Password.RequiredUniqueChars": "अद्वितीय वर्णों की न्यूनतम संख्या जिसमें एक पासवर्ड होना चाहिए।", + "Description:Abp.Identity.Password.RequireNonAlphanumeric": "यदि पासवर्ड में गैर-अल्फ़ान्यूमेरिक वर्ण होना चाहिए।", + "Description:Abp.Identity.Password.RequireLowercase": "यदि पासवर्ड में ASCII वर्ण कम होना चाहिए।", + "Description:Abp.Identity.Password.RequireUppercase": "यदि पासवर्ड में ऊपरी मामला ASCII वर्ण होना चाहिए।", + "Description:Abp.Identity.Password.RequireDigit": "यदि पासवर्ड में एक अंक होना चाहिए।", + "Description:Abp.Identity.Lockout.AllowedForNewUsers": "क्या कोई नया उपयोगकर्ता लॉक किया जा सकता है।", + "Description:Abp.Identity.Lockout.LockoutDuration": "जब लॉकआउट होता है, तो उपयोगकर्ता की अवधि लॉक हो जाती है।", + "Description:Abp.Identity.Lockout.MaxFailedAccessAttempts": "उपयोगकर्ता द्वारा लॉक किए जाने से पहले अनुमति प्राप्त विफल प्रयासों की संख्या, यह मानकर कि लॉक आउट सक्षम है।", + "Description:Abp.Identity.SignIn.RequireConfirmedEmail": "क्या साइन इन करने के लिए किसी पुष्टिकृत ईमेल पते की आवश्यकता है।", + "Description:Abp.Identity.SignIn.EnablePhoneNumberConfirmation": "क्या उपयोगकर्ता द्वारा फोननंबर की पुष्टि की जा सकती है।", + "Description:Abp.Identity.SignIn.RequireConfirmedPhoneNumber": "साइन इन करने के लिए एक पुष्टिकरण टेलीफोन नंबर की आवश्यकता है या नहीं।", + "Description:Abp.Identity.User.IsUserNameUpdateEnabled": "उपयोगकर्ता द्वारा उपयोगकर्ता नाम अपडेट किया जा सकता है या नहीं।", + "Description:Abp.Identity.User.IsEmailUpdateEnabled": "क्या उपयोगकर्ता द्वारा ईमेल को अपडेट किया जा सकता है।" + } +} \ No newline at end of file diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/it.json b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/it.json new file mode 100644 index 0000000000..48bd4e8771 --- /dev/null +++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/it.json @@ -0,0 +1,110 @@ +{ + "culture": "it", + "texts": { + "Menu:IdentityManagement": "Gestione dell'identità", + "Users": "Utenti", + "NewUser": "Nuovo utente", + "UserName": "Nome utente", + "EmailAddress": "Indirizzo e-mail", + "PhoneNumber": "Numero di telefono", + "UserInformations": "Informazioni utente", + "DisplayName:IsDefault": "Predefinito", + "DisplayName:IsStatic": "Statico", + "DisplayName:IsPublic": "Pubblico", + "Roles": "Ruoli", + "Password": "Parola d'ordine", + "PersonalInfo": "Il mio profilo", + "PersonalSettings": "Impostazioni personali", + "UserDeletionConfirmationMessage": "L'utente \"{0}\" verrà eliminato. Lo confermi?", + "RoleDeletionConfirmationMessage": "Il ruolo \"{0}\" verrà eliminato. Lo confermi?", + "DisplayName:RoleName": "Nome del ruolo", + "DisplayName:UserName": "Nome utente", + "DisplayName:Name": "Nome", + "DisplayName:Surname": "Cognome", + "DisplayName:Password": "Parola d'ordine", + "DisplayName:Email": "Indirizzo e-mail", + "DisplayName:PhoneNumber": "Numero di telefono", + "DisplayName:TwoFactorEnabled": "Verifica a due fattori", + "DisplayName:LockoutEnabled": "Blocca account dopo tentativi di accesso falliti", + "NewRole": "Nuovo ruolo", + "RoleName": "Nome del ruolo", + "CreationTime": "Tempo di creazione", + "Permissions": "Autorizzazioni", + "DisplayName:CurrentPassword": "Password attuale", + "DisplayName:NewPassword": "Nuova password", + "DisplayName:NewPasswordConfirm": "Conferma la nuova password", + "PasswordChangedMessage": "La tua password è stata cambiata con successo.", + "PersonalSettingsSavedMessage": "Le tue impostazioni personali sono state salvate con successo.", + "Volo.Abp.Identity:DefaultError": "Si è verificato un errore sconosciuto.", + "Volo.Abp.Identity:ConcurrencyFailure": "Errore di concorrenza ottimistica, l'oggetto è stato modificato.", + "Volo.Abp.Identity:DuplicateEmail": "L'email \"{0}\" è già stata accettata.", + "Volo.Abp.Identity:DuplicateRoleName": "Il nome del ruolo \"{0}\" è già stato utilizzato.", + "Volo.Abp.Identity:DuplicateUserName": "Il nome utente \"{0}\" è già in uso.", + "Volo.Abp.Identity:InvalidEmail": "L'email \"{0}\" non è valida.", + "Volo.Abp.Identity:InvalidPasswordHasherCompatibilityMode": "Il PasswordHasherCompatibilityMode fornito non è valido.", + "Volo.Abp.Identity:InvalidPasswordHasherIterationCount": "Il conteggio delle iterazioni deve essere un numero intero positivo.", + "Volo.Abp.Identity:InvalidRoleName": "Il nome del ruolo \"{0}\" non è valido.", + "Volo.Abp.Identity:InvalidToken": "Gettone non valido.", + "Volo.Abp.Identity:InvalidUserName": "Il nome utente \"{0}\" non è valido, può contenere solo lettere o cifre.", + "Volo.Abp.Identity:LoginAlreadyAssociated": "Esiste già un utente con questo accesso.", + "Volo.Abp.Identity:PasswordMismatch": "Password errata.", + "Volo.Abp.Identity:PasswordRequiresDigit": "Le password devono contenere almeno una cifra (\"0\" - \"9\").", + "Volo.Abp.Identity:PasswordRequiresLower": "Le password devono contenere almeno una minuscola (\"a\" - \"z\").", + "Volo.Abp.Identity:PasswordRequiresNonAlphanumeric": "Le password devono contenere almeno un carattere non alfanumerico.", + "Volo.Abp.Identity:PasswordRequiresUpper": "Le password devono contenere almeno una maiuscola (\"A\" - \"Z\").", + "Volo.Abp.Identity:PasswordTooShort": "Le password devono contenere almeno {0} caratteri.", + "Volo.Abp.Identity:RoleNotFound": "Il ruolo {0} non esiste.", + "Volo.Abp.Identity:UserAlreadyHasPassword": "L'utente ha già una password impostata.", + "Volo.Abp.Identity:UserAlreadyInRole": "Utente già nel ruolo \"{0}\".", + "Volo.Abp.Identity:UserLockedOut": "L'utente è bloccato.", + "Volo.Abp.Identity:UserLockoutNotEnabled": "Il blocco non è abilitato per questo utente.", + "Volo.Abp.Identity:UserNameNotFound": "L'utente {0} non esiste.", + "Volo.Abp.Identity:UserNotInRole": "L'utente non è nel ruolo \"{0}\".", + "Volo.Abp.Identity:PasswordConfirmationFailed": "La password non corrisponde alla password di conferma.", + "Volo.Abp.Identity:010001": "Non puoi cancellare il tuo account!", + "Volo.Abp.Identity:010002": "Impossibile impostare più di {MaxUserMembershipCount} unità organizzativa per un utente!", + "Volo.Abp.Identity:010003": "Non è possibile modificare la password di un utente connesso esternamente!", + "Volo.Abp.Identity:010004": "Esiste già un'unità organizzativa con nome {0}. Non è possibile creare due unità con lo stesso nome nello stesso livello.", + "Volo.Abp.Identity:010005": "I ruoli statici non possono essere rinominati.", + "Volo.Abp.Identity:010006": "I ruoli statici non possono essere eliminati.", + "Volo.Abp.Identity:010007": "Non puoi modificare l'impostazione dei due fattori.", + "Volo.Abp.Identity:010008": "Non è consentito modificare l'impostazione a due fattori.", + "Identity.OrganizationUnit.MaxUserMembershipCount": "Numero massimo consentito di membri dell'unità organizzativa per un utente", + "Permission:IdentityManagement": "Gestione dell'identità", + "Permission:RoleManagement": "Gestione dei ruoli", + "Permission:Create": "Creare", + "Permission:Edit": "modificare", + "Permission:Delete": "Elimina", + "Permission:ChangePermissions": "Modifica le autorizzazioni", + "Permission:UserManagement": "Gestione utenti", + "Permission:UserLookup": "Ricerca utente", + "DisplayName:Abp.Identity.Password.RequiredLength": "Lunghezza richiesta", + "DisplayName:Abp.Identity.Password.RequiredUniqueChars": "Numero di caratteri univoci richiesto", + "DisplayName:Abp.Identity.Password.RequireNonAlphanumeric": "Carattere non alfanumerico richiesto", + "DisplayName:Abp.Identity.Password.RequireLowercase": "Carattere minuscolo richiesto", + "DisplayName:Abp.Identity.Password.RequireUppercase": "Carattere maiuscolo obbligatorio", + "DisplayName:Abp.Identity.Password.RequireDigit": "Cifra richiesta", + "DisplayName:Abp.Identity.Lockout.AllowedForNewUsers": "Abilitato per i nuovi utenti", + "DisplayName:Abp.Identity.Lockout.LockoutDuration": "Durata blocco (secondi)", + "DisplayName:Abp.Identity.Lockout.MaxFailedAccessAttempts": "Numero massimo di tentativi di accesso non riusciti", + "DisplayName:Abp.Identity.SignIn.RequireConfirmedEmail": "Richiedi email confermata", + "DisplayName:Abp.Identity.SignIn.EnablePhoneNumberConfirmation": "Consenti agli utenti di confermare il proprio numero di telefono", + "DisplayName:Abp.Identity.SignIn.RequireConfirmedPhoneNumber": "Richiedi un numero di telefono confermato", + "DisplayName:Abp.Identity.User.IsUserNameUpdateEnabled": "Consenti agli utenti di modificare i propri nomi utente", + "DisplayName:Abp.Identity.User.IsEmailUpdateEnabled": "Consenti agli utenti di modificare i propri indirizzi email", + "Description:Abp.Identity.Password.RequiredLength": "La lunghezza minima che deve essere una password.", + "Description:Abp.Identity.Password.RequiredUniqueChars": "Il numero minimo di caratteri univoci che una password deve contenere.", + "Description:Abp.Identity.Password.RequireNonAlphanumeric": "Se le password devono contenere un carattere non alfanumerico.", + "Description:Abp.Identity.Password.RequireLowercase": "Se le password devono contenere un carattere ASCII minuscolo.", + "Description:Abp.Identity.Password.RequireUppercase": "Se le password devono contenere un carattere ASCII maiuscolo.", + "Description:Abp.Identity.Password.RequireDigit": "Se le password devono contenere una cifra.", + "Description:Abp.Identity.Lockout.AllowedForNewUsers": "Se un nuovo utente può essere bloccato.", + "Description:Abp.Identity.Lockout.LockoutDuration": "La durata per cui un utente viene bloccato quando si verifica un blocco.", + "Description:Abp.Identity.Lockout.MaxFailedAccessAttempts": "Il numero di tentativi di accesso non riusciti consentiti prima che un utente venga bloccato, a condizione che il blocco sia abilitato.", + "Description:Abp.Identity.SignIn.RequireConfirmedEmail": "Indica se è necessario un indirizzo email confermato per accedere.", + "Description:Abp.Identity.SignIn.EnablePhoneNumberConfirmation": "Se il phoneNumber può essere confermato dall'utente.", + "Description:Abp.Identity.SignIn.RequireConfirmedPhoneNumber": "Indica se è necessario un numero di telefono confermato per accedere.", + "Description:Abp.Identity.User.IsUserNameUpdateEnabled": "Se il nome utente può essere aggiornato dall'utente.", + "Description:Abp.Identity.User.IsEmailUpdateEnabled": "Se l'email può essere aggiornata dall'utente." + } +} \ No newline at end of file diff --git a/modules/identity/src/Volo.Abp.Identity.Domain/Volo.Abp.Identity.Domain.abppkg.json b/modules/identity/src/Volo.Abp.Identity.Domain/Volo.Abp.Identity.Domain.abppkg.json new file mode 100644 index 0000000000..1d574efe45 --- /dev/null +++ b/modules/identity/src/Volo.Abp.Identity.Domain/Volo.Abp.Identity.Domain.abppkg.json @@ -0,0 +1,3 @@ +{ + "role": "lib.domain" +} \ No newline at end of file diff --git a/modules/identity/src/Volo.Abp.Identity.EntityFrameworkCore/Volo.Abp.Identity.EntityFrameworkCore.abppkg.json b/modules/identity/src/Volo.Abp.Identity.EntityFrameworkCore/Volo.Abp.Identity.EntityFrameworkCore.abppkg.json new file mode 100644 index 0000000000..e1c64f0175 --- /dev/null +++ b/modules/identity/src/Volo.Abp.Identity.EntityFrameworkCore/Volo.Abp.Identity.EntityFrameworkCore.abppkg.json @@ -0,0 +1,3 @@ +{ + "role": "lib.ef" +} \ No newline at end of file diff --git a/modules/identity/src/Volo.Abp.Identity.HttpApi.Client/Volo.Abp.Identity.HttpApi.Client.abppkg.json b/modules/identity/src/Volo.Abp.Identity.HttpApi.Client/Volo.Abp.Identity.HttpApi.Client.abppkg.json new file mode 100644 index 0000000000..7deef5e383 --- /dev/null +++ b/modules/identity/src/Volo.Abp.Identity.HttpApi.Client/Volo.Abp.Identity.HttpApi.Client.abppkg.json @@ -0,0 +1,3 @@ +{ + "role": "lib.http-api-client" +} \ No newline at end of file diff --git a/modules/identity/src/Volo.Abp.Identity.HttpApi/Volo.Abp.Identity.HttpApi.abppkg.json b/modules/identity/src/Volo.Abp.Identity.HttpApi/Volo.Abp.Identity.HttpApi.abppkg.json new file mode 100644 index 0000000000..515bfe64c4 --- /dev/null +++ b/modules/identity/src/Volo.Abp.Identity.HttpApi/Volo.Abp.Identity.HttpApi.abppkg.json @@ -0,0 +1,3 @@ +{ + "role": "lib.http-api" +} \ No newline at end of file diff --git a/modules/identity/src/Volo.Abp.Identity.MongoDB/Volo.Abp.Identity.MongoDB.abppkg.json b/modules/identity/src/Volo.Abp.Identity.MongoDB/Volo.Abp.Identity.MongoDB.abppkg.json new file mode 100644 index 0000000000..8b23fd1e69 --- /dev/null +++ b/modules/identity/src/Volo.Abp.Identity.MongoDB/Volo.Abp.Identity.MongoDB.abppkg.json @@ -0,0 +1,3 @@ +{ + "role": "lib.mongodb" +} \ No newline at end of file diff --git a/modules/identity/src/Volo.Abp.Identity.Web/Navigation/AbpIdentityWebMainMenuContributor.cs b/modules/identity/src/Volo.Abp.Identity.Web/Navigation/AbpIdentityWebMainMenuContributor.cs index 2f48318511..a6355a794a 100644 --- a/modules/identity/src/Volo.Abp.Identity.Web/Navigation/AbpIdentityWebMainMenuContributor.cs +++ b/modules/identity/src/Volo.Abp.Identity.Web/Navigation/AbpIdentityWebMainMenuContributor.cs @@ -4,6 +4,7 @@ using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Localization; using Volo.Abp.Identity.Localization; using Volo.Abp.UI.Navigation; +using Volo.Abp.Authorization.Permissions; namespace Volo.Abp.Identity.Web.Navigation { @@ -19,8 +20,8 @@ namespace Volo.Abp.Identity.Web.Navigation var l = context.GetLocalizer(); var identityMenuItem = new ApplicationMenuItem(IdentityMenuNames.GroupName, l["Menu:IdentityManagement"], icon: "fa fa-id-card-o"); - identityMenuItem.AddItem(new ApplicationMenuItem(IdentityMenuNames.Roles, l["Roles"], url: "~/Identity/Roles", requiredPermissionName: IdentityPermissions.Roles.Default)); - identityMenuItem.AddItem(new ApplicationMenuItem(IdentityMenuNames.Users, l["Users"], url: "~/Identity/Users", requiredPermissionName: IdentityPermissions.Users.Default)); + identityMenuItem.AddItem(new ApplicationMenuItem(IdentityMenuNames.Roles, l["Roles"], url: "~/Identity/Roles").RequirePermissions(IdentityPermissions.Roles.Default)); + identityMenuItem.AddItem(new ApplicationMenuItem(IdentityMenuNames.Users, l["Users"], url: "~/Identity/Users").RequirePermissions( IdentityPermissions.Users.Default)); context.Menu.GetAdministration().AddItem(identityMenuItem); diff --git a/modules/identity/src/Volo.Abp.Identity.Web/Volo.Abp.Identity.Web.abppkg.json b/modules/identity/src/Volo.Abp.Identity.Web/Volo.Abp.Identity.Web.abppkg.json new file mode 100644 index 0000000000..930c4018b3 --- /dev/null +++ b/modules/identity/src/Volo.Abp.Identity.Web/Volo.Abp.Identity.Web.abppkg.json @@ -0,0 +1,3 @@ +{ + "role": "lib.mvc" +} \ No newline at end of file diff --git a/modules/identity/src/Volo.Abp.PermissionManagement.Domain.Identity/Volo.Abp.PermissionManagement.Domain.Identity.abppkg.json b/modules/identity/src/Volo.Abp.PermissionManagement.Domain.Identity/Volo.Abp.PermissionManagement.Domain.Identity.abppkg.json new file mode 100644 index 0000000000..9e26dfeeb6 --- /dev/null +++ b/modules/identity/src/Volo.Abp.PermissionManagement.Domain.Identity/Volo.Abp.PermissionManagement.Domain.Identity.abppkg.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/modules/identity/test/Volo.Abp.Identity.Application.Tests/Volo.Abp.Identity.Application.Tests.abppkg.json b/modules/identity/test/Volo.Abp.Identity.Application.Tests/Volo.Abp.Identity.Application.Tests.abppkg.json new file mode 100644 index 0000000000..a686451fbc --- /dev/null +++ b/modules/identity/test/Volo.Abp.Identity.Application.Tests/Volo.Abp.Identity.Application.Tests.abppkg.json @@ -0,0 +1,3 @@ +{ + "role": "lib.test" +} \ No newline at end of file diff --git a/modules/identity/test/Volo.Abp.Identity.AspNetCore.Tests/Volo.Abp.Identity.AspNetCore.Tests.abppkg.json b/modules/identity/test/Volo.Abp.Identity.AspNetCore.Tests/Volo.Abp.Identity.AspNetCore.Tests.abppkg.json new file mode 100644 index 0000000000..a686451fbc --- /dev/null +++ b/modules/identity/test/Volo.Abp.Identity.AspNetCore.Tests/Volo.Abp.Identity.AspNetCore.Tests.abppkg.json @@ -0,0 +1,3 @@ +{ + "role": "lib.test" +} \ No newline at end of file diff --git a/modules/identity/test/Volo.Abp.Identity.Domain.Tests/Volo.Abp.Identity.Domain.Tests.abppkg.json b/modules/identity/test/Volo.Abp.Identity.Domain.Tests/Volo.Abp.Identity.Domain.Tests.abppkg.json new file mode 100644 index 0000000000..a686451fbc --- /dev/null +++ b/modules/identity/test/Volo.Abp.Identity.Domain.Tests/Volo.Abp.Identity.Domain.Tests.abppkg.json @@ -0,0 +1,3 @@ +{ + "role": "lib.test" +} \ No newline at end of file diff --git a/modules/identity/test/Volo.Abp.Identity.Domain.Tests/Volo/Abp/Identity/LocalizationExtensions/hi.json b/modules/identity/test/Volo.Abp.Identity.Domain.Tests/Volo/Abp/Identity/LocalizationExtensions/hi.json new file mode 100644 index 0000000000..e78aab590d --- /dev/null +++ b/modules/identity/test/Volo.Abp.Identity.Domain.Tests/Volo/Abp/Identity/LocalizationExtensions/hi.json @@ -0,0 +1,7 @@ +{ + "culture": "hi", + "texts": { + "Volo.Abp.Identity:PasswordTooShort": "पासवर्ड की लंबाई {0} वर्णों से अधिक होनी चाहिए।", + "Volo.Abp.Identity:PasswordRequiresNonAlphanumeric": "पासवर्ड में कम से कम एक गैर-अल्फ़ान्यूमेरिक वर्ण होना चाहिए।" + } +} \ No newline at end of file diff --git a/modules/identity/test/Volo.Abp.Identity.Domain.Tests/Volo/Abp/Identity/LocalizationExtensions/it.json b/modules/identity/test/Volo.Abp.Identity.Domain.Tests/Volo/Abp/Identity/LocalizationExtensions/it.json new file mode 100644 index 0000000000..ee639b55c1 --- /dev/null +++ b/modules/identity/test/Volo.Abp.Identity.Domain.Tests/Volo/Abp/Identity/LocalizationExtensions/it.json @@ -0,0 +1,7 @@ +{ + "culture": "it", + "texts": { + "Volo.Abp.Identity:PasswordTooShort": "La lunghezza della password deve essere maggiore di {0} caratteri.", + "Volo.Abp.Identity:PasswordRequiresNonAlphanumeric": "La password deve contenere almeno un carattere non alfanumerico." + } +} \ No newline at end of file diff --git a/modules/identity/test/Volo.Abp.Identity.EntityFrameworkCore.Tests/Volo.Abp.Identity.EntityFrameworkCore.Tests.abppkg.json b/modules/identity/test/Volo.Abp.Identity.EntityFrameworkCore.Tests/Volo.Abp.Identity.EntityFrameworkCore.Tests.abppkg.json new file mode 100644 index 0000000000..a686451fbc --- /dev/null +++ b/modules/identity/test/Volo.Abp.Identity.EntityFrameworkCore.Tests/Volo.Abp.Identity.EntityFrameworkCore.Tests.abppkg.json @@ -0,0 +1,3 @@ +{ + "role": "lib.test" +} \ No newline at end of file diff --git a/modules/identity/test/Volo.Abp.Identity.MongoDB.Tests/Volo.Abp.Identity.MongoDB.Tests.abppkg.json b/modules/identity/test/Volo.Abp.Identity.MongoDB.Tests/Volo.Abp.Identity.MongoDB.Tests.abppkg.json new file mode 100644 index 0000000000..a686451fbc --- /dev/null +++ b/modules/identity/test/Volo.Abp.Identity.MongoDB.Tests/Volo.Abp.Identity.MongoDB.Tests.abppkg.json @@ -0,0 +1,3 @@ +{ + "role": "lib.test" +} \ No newline at end of file diff --git a/modules/identity/test/Volo.Abp.Identity.TestBase/Volo.Abp.Identity.TestBase.abppkg.json b/modules/identity/test/Volo.Abp.Identity.TestBase/Volo.Abp.Identity.TestBase.abppkg.json new file mode 100644 index 0000000000..9e26dfeeb6 --- /dev/null +++ b/modules/identity/test/Volo.Abp.Identity.TestBase/Volo.Abp.Identity.TestBase.abppkg.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/modules/identityserver/Volo.Abp.IdentityServer.abpmdl.json b/modules/identityserver/Volo.Abp.IdentityServer.abpmdl.json index b56f99933a..01fe37ad9f 100644 --- a/modules/identityserver/Volo.Abp.IdentityServer.abpmdl.json +++ b/modules/identityserver/Volo.Abp.IdentityServer.abpmdl.json @@ -1,76 +1,46 @@ { "folders": { - "src": {}, - "test": {} - }, - "imports": { - "Volo.Abp.Identity": { - "path": "../identity/Volo.Abp.Identity.abpmdl.json" - }, - "Volo.Abp.PermissionManagement": { - "path": "../permission-management/Volo.Abp.PermissionManagement.abpmdl.json" + "items": { + "src": {}, + "test": {} } }, "packages": { - "Volo.Abp.IdentityServer.Domain.Shared": { - "path": "src/Volo.Abp.IdentityServer.Domain.Shared/Volo.Abp.IdentityServer.Domain.Shared.csproj", - "folder": "src", - "includes": { - "lib.domain.shared": {} - } - }, "Volo.Abp.IdentityServer.Domain": { - "path": "src/Volo.Abp.IdentityServer.Domain/Volo.Abp.IdentityServer.Domain.csproj", - "folder": "src", - "includes": { - "lib.domain": {} - } + "path": "src/Volo.Abp.IdentityServer.Domain/Volo.Abp.IdentityServer.Domain.abppkg.json", + "folder": "src" + }, + "Volo.Abp.IdentityServer.Domain.Shared": { + "path": "src/Volo.Abp.IdentityServer.Domain.Shared/Volo.Abp.IdentityServer.Domain.Shared.abppkg.json", + "folder": "src" }, "Volo.Abp.IdentityServer.EntityFrameworkCore": { - "path": "src/Volo.Abp.IdentityServer.EntityFrameworkCore/Volo.Abp.IdentityServer.EntityFrameworkCore.csproj", - "folder": "src", - "includes": { - "lib.ef": {} - } + "path": "src/Volo.Abp.IdentityServer.EntityFrameworkCore/Volo.Abp.IdentityServer.EntityFrameworkCore.abppkg.json", + "folder": "src" }, - "Volo.Abp.IdentityServer.MongoDB": { - "path": "src/Volo.Abp.IdentityServer.MongoDB/Volo.Abp.IdentityServer.MongoDB.csproj", - "folder": "src", - "includes": { - "lib.mongodb": {} - } + "Volo.Abp.IdentityServer.EntityFrameworkCore.Tests": { + "path": "test/Volo.Abp.IdentityServer.EntityFrameworkCore.Tests/Volo.Abp.IdentityServer.EntityFrameworkCore.Tests.abppkg.json", + "folder": "test" }, - "Volo.Abp.PermissionManagement.Domain.IdentityServer": { - "path": "src/Volo.Abp.PermissionManagement.Domain.IdentityServer/Volo.Abp.PermissionManagement.Domain.IdentityServer.csproj", + "Volo.Abp.IdentityServer.MongoDB": { + "path": "src/Volo.Abp.IdentityServer.MongoDB/Volo.Abp.IdentityServer.MongoDB.abppkg.json", "folder": "src" }, "Volo.Abp.IdentityServer.TestBase": { - "path": "test/Volo.Abp.IdentityServer.TestBase/Volo.Abp.IdentityServer.TestBase.csproj", - "folder": "test", - "includes": { - "lib.test": {} - } + "path": "test/Volo.Abp.IdentityServer.TestBase/Volo.Abp.IdentityServer.TestBase.abppkg.json", + "folder": "test" }, - "Volo.Abp.IdentityServer.Domain.Tests": { - "path": "test/Volo.Abp.IdentityServer.Domain.Tests/Volo.Abp.IdentityServer.Domain.Tests.csproj", - "folder": "test", - "includes": { - "lib.test": {} - } + "Volo.Abp.IdentityServer.MongoDB.Tests": { + "path": "test/Volo.Abp.IdentityServer.MongoDB.Tests/Volo.Abp.IdentityServer.MongoDB.Tests.abppkg.json", + "folder": "test" }, - "Volo.Abp.IdentityServer.EntityFrameworkCore.Tests": { - "path": "test/Volo.Abp.IdentityServer.EntityFrameworkCore.Tests/Volo.Abp.IdentityServer.EntityFrameworkCore.Tests.csproj", - "folder": "test", - "includes": { - "lib.test": {} - } + "Volo.Abp.IdentityServer.Domain.Tests": { + "path": "test/Volo.Abp.IdentityServer.Domain.Tests/Volo.Abp.IdentityServer.Domain.Tests.abppkg.json", + "folder": "test" }, - "Volo.Abp.IdentityServer.MongoDB.Tests": { - "path": "test/Volo.Abp.IdentityServer.MongoDB.Tests/Volo.Abp.IdentityServer.MongoDB.Tests.csproj", - "folder": "test", - "includes": { - "lib.test": {} - } + "Volo.Abp.PermissionManagement.Domain.IdentityServer": { + "path": "src/Volo.Abp.PermissionManagement.Domain.IdentityServer/Volo.Abp.PermissionManagement.Domain.IdentityServer.abppkg.json", + "folder": "src" } } } \ No newline at end of file diff --git a/modules/identityserver/src/Volo.Abp.IdentityServer.Domain.Shared/Volo.Abp.IdentityServer.Domain.Shared.abppkg.json b/modules/identityserver/src/Volo.Abp.IdentityServer.Domain.Shared/Volo.Abp.IdentityServer.Domain.Shared.abppkg.json new file mode 100644 index 0000000000..8b3de05f76 --- /dev/null +++ b/modules/identityserver/src/Volo.Abp.IdentityServer.Domain.Shared/Volo.Abp.IdentityServer.Domain.Shared.abppkg.json @@ -0,0 +1,3 @@ +{ + "role": "lib.domain-shared" +} \ No newline at end of file diff --git a/modules/identityserver/src/Volo.Abp.IdentityServer.Domain.Shared/Volo/Abp/IdentityServer/Localization/Resources/hi.json b/modules/identityserver/src/Volo.Abp.IdentityServer.Domain.Shared/Volo/Abp/IdentityServer/Localization/Resources/hi.json new file mode 100644 index 0000000000..4a6aa5909e --- /dev/null +++ b/modules/identityserver/src/Volo.Abp.IdentityServer.Domain.Shared/Volo/Abp/IdentityServer/Localization/Resources/hi.json @@ -0,0 +1,14 @@ +{ + "culture": "hi", + "texts": { + "Volo.IdentityServer:DuplicateIdentityResourceName": "पहचान संसाधन नाम पहले से मौजूद है: {नाम}", + "Volo.IdentityServer:DuplicateApiResourceName": "आपी संसाधन नाम पहले से मौजूद है: {नाम}", + "Volo.IdentityServer:DuplicateApiScopeName": "आपी स्कोप नाम पहले से मौजूद है: {नाम}", + "Volo.IdentityServer:DuplicateClientId": "ClientId पहले से मौजूद है: {ClientId}", + "UserLockedOut": "अमान्य लॉगिन प्रयासों के कारण उपयोगकर्ता खाता बंद कर दिया गया है। कृपया थोड़ी देर प्रतीक्षा करें और पुन: प्रयास करें।", + "InvalidUserNameOrPassword": "अमान्य उपयोगकर्ता नाम या पासवर्ड!", + "LoginIsNotAllowed": "आपको लॉगिन करने की अनुमति नहीं है! आपको अपने ईमेल / फोन नंबर की पुष्टि करनी होगी।", + "InvalidUsername": "अमान्य उपयोगकर्ता नाम या पासवर्ड!", + "TheTargetUserIsNotLinkedToYou": "लक्ष्य उपयोगकर्ता आपसे जुड़ा नहीं है!" + } +} \ No newline at end of file diff --git a/modules/identityserver/src/Volo.Abp.IdentityServer.Domain.Shared/Volo/Abp/IdentityServer/Localization/Resources/it.json b/modules/identityserver/src/Volo.Abp.IdentityServer.Domain.Shared/Volo/Abp/IdentityServer/Localization/Resources/it.json new file mode 100644 index 0000000000..ca44d39a38 --- /dev/null +++ b/modules/identityserver/src/Volo.Abp.IdentityServer.Domain.Shared/Volo/Abp/IdentityServer/Localization/Resources/it.json @@ -0,0 +1,14 @@ +{ + "culture": "it", + "texts": { + "Volo.IdentityServer:DuplicateIdentityResourceName": "Il nome della risorsa identità esiste già: {Name}", + "Volo.IdentityServer:DuplicateApiResourceName": "Il nome della risorsa API esiste già: {Name}", + "Volo.IdentityServer:DuplicateApiScopeName": "Il nome dell'ambito API esiste già: {Name}", + "Volo.IdentityServer:DuplicateClientId": "ClientId già esistente: {ClientId}", + "UserLockedOut": "L'account utente è stato bloccato a causa di tentativi di accesso non validi. Attendi qualche istante e riprova.", + "InvalidUserNameOrPassword": "Username o password non validi!", + "LoginIsNotAllowed": "Non sei autorizzato ad accedere! Devi confermare la tua email / numero di telefono.", + "InvalidUsername": "Username o password non validi!", + "TheTargetUserIsNotLinkedToYou": "L'utente di destinazione non è collegato a te!" + } +} \ No newline at end of file diff --git a/modules/identityserver/src/Volo.Abp.IdentityServer.Domain/Volo.Abp.IdentityServer.Domain.abppkg.json b/modules/identityserver/src/Volo.Abp.IdentityServer.Domain/Volo.Abp.IdentityServer.Domain.abppkg.json new file mode 100644 index 0000000000..1d574efe45 --- /dev/null +++ b/modules/identityserver/src/Volo.Abp.IdentityServer.Domain/Volo.Abp.IdentityServer.Domain.abppkg.json @@ -0,0 +1,3 @@ +{ + "role": "lib.domain" +} \ No newline at end of file diff --git a/modules/identityserver/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/AbpStrictRedirectUriValidator.cs b/modules/identityserver/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/AbpStrictRedirectUriValidator.cs index 359babde7e..a4459d99e2 100644 --- a/modules/identityserver/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/AbpStrictRedirectUriValidator.cs +++ b/modules/identityserver/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/AbpStrictRedirectUriValidator.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Linq; using System.Threading.Tasks; using IdentityServer4.Models; using IdentityServer4.Validation; @@ -33,7 +34,9 @@ namespace Volo.Abp.IdentityServer var extractResult = FormattedStringValueExtracter.Extract(requestedUri, url, ignoreCase: true); if (extractResult.IsMatch) { - return Task.FromResult(true); + return Task.FromResult(extractResult.Matches + .Aggregate(url, (current, nameValue) => current.Replace($"{{{nameValue.Name}}}", nameValue.Value)) + .Contains(requestedUri, StringComparison.OrdinalIgnoreCase)); } if (url.Replace("{0}.", "").Contains(requestedUri, StringComparison.OrdinalIgnoreCase)) diff --git a/modules/identityserver/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/AbpWildcardSubdomainCorsPolicyService.cs b/modules/identityserver/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/AbpWildcardSubdomainCorsPolicyService.cs index 1a9d146ca9..daf8d1f6f2 100644 --- a/modules/identityserver/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/AbpWildcardSubdomainCorsPolicyService.cs +++ b/modules/identityserver/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/AbpWildcardSubdomainCorsPolicyService.cs @@ -1,4 +1,5 @@ using System; +using System.Linq; using System.Threading.Tasks; using IdentityServer4.Configuration; using Microsoft.Extensions.Options; @@ -32,7 +33,8 @@ namespace Volo.Abp.IdentityServer var extractResult = FormattedStringValueExtracter.Extract(origin, url, ignoreCase: true); if (extractResult.IsMatch) { - return true; + return extractResult.Matches.Aggregate(url, (current, nameValue) => current.Replace($"{{{nameValue.Name}}}", nameValue.Value)) + .Contains(origin, StringComparison.OrdinalIgnoreCase); } if (url.Replace("{0}.", "").Contains(origin, StringComparison.OrdinalIgnoreCase)) diff --git a/modules/identityserver/src/Volo.Abp.IdentityServer.EntityFrameworkCore/Volo.Abp.IdentityServer.EntityFrameworkCore.abppkg.json b/modules/identityserver/src/Volo.Abp.IdentityServer.EntityFrameworkCore/Volo.Abp.IdentityServer.EntityFrameworkCore.abppkg.json new file mode 100644 index 0000000000..e1c64f0175 --- /dev/null +++ b/modules/identityserver/src/Volo.Abp.IdentityServer.EntityFrameworkCore/Volo.Abp.IdentityServer.EntityFrameworkCore.abppkg.json @@ -0,0 +1,3 @@ +{ + "role": "lib.ef" +} \ No newline at end of file diff --git a/modules/identityserver/src/Volo.Abp.IdentityServer.MongoDB/Volo.Abp.IdentityServer.MongoDB.abppkg.json b/modules/identityserver/src/Volo.Abp.IdentityServer.MongoDB/Volo.Abp.IdentityServer.MongoDB.abppkg.json new file mode 100644 index 0000000000..8b23fd1e69 --- /dev/null +++ b/modules/identityserver/src/Volo.Abp.IdentityServer.MongoDB/Volo.Abp.IdentityServer.MongoDB.abppkg.json @@ -0,0 +1,3 @@ +{ + "role": "lib.mongodb" +} \ No newline at end of file diff --git a/modules/identityserver/src/Volo.Abp.PermissionManagement.Domain.IdentityServer/Volo.Abp.PermissionManagement.Domain.IdentityServer.abppkg.json b/modules/identityserver/src/Volo.Abp.PermissionManagement.Domain.IdentityServer/Volo.Abp.PermissionManagement.Domain.IdentityServer.abppkg.json new file mode 100644 index 0000000000..9e26dfeeb6 --- /dev/null +++ b/modules/identityserver/src/Volo.Abp.PermissionManagement.Domain.IdentityServer/Volo.Abp.PermissionManagement.Domain.IdentityServer.abppkg.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/modules/identityserver/test/Volo.Abp.IdentityServer.Domain.Tests/Volo.Abp.IdentityServer.Domain.Tests.abppkg.json b/modules/identityserver/test/Volo.Abp.IdentityServer.Domain.Tests/Volo.Abp.IdentityServer.Domain.Tests.abppkg.json new file mode 100644 index 0000000000..a686451fbc --- /dev/null +++ b/modules/identityserver/test/Volo.Abp.IdentityServer.Domain.Tests/Volo.Abp.IdentityServer.Domain.Tests.abppkg.json @@ -0,0 +1,3 @@ +{ + "role": "lib.test" +} \ No newline at end of file diff --git a/modules/identityserver/test/Volo.Abp.IdentityServer.Domain.Tests/Volo/Abp/IdentityServer/AbpStrictRedirectUriValidator_Tests.cs b/modules/identityserver/test/Volo.Abp.IdentityServer.Domain.Tests/Volo/Abp/IdentityServer/AbpStrictRedirectUriValidator_Tests.cs index a455cd9811..7f00d2e355 100644 --- a/modules/identityserver/test/Volo.Abp.IdentityServer.Domain.Tests/Volo/Abp/IdentityServer/AbpStrictRedirectUriValidator_Tests.cs +++ b/modules/identityserver/test/Volo.Abp.IdentityServer.Domain.Tests/Volo/Abp/IdentityServer/AbpStrictRedirectUriValidator_Tests.cs @@ -54,6 +54,7 @@ namespace Volo.Abp.IdentityServer (await _abpStrictRedirectUriValidator.IsRedirectUriValidAsync("http://ng.abp.io", _testClient)).ShouldBeTrue(); (await _abpStrictRedirectUriValidator.IsRedirectUriValidAsync("https://api.t1.abp:8080/", _testClient)).ShouldBeFalse(); (await _abpStrictRedirectUriValidator.IsRedirectUriValidAsync("http://ng.t1.abp.io", _testClient)).ShouldBeFalse(); + (await _abpStrictRedirectUriValidator.IsRedirectUriValidAsync("http://t1.ng.abp.io/index.html.mydomain.com", _testClient)).ShouldBeFalse(); } [Fact] @@ -68,6 +69,7 @@ namespace Volo.Abp.IdentityServer (await _abpStrictRedirectUriValidator.IsPostLogoutRedirectUriValidAsync("http://ng.abp.io", _testClient)).ShouldBeTrue(); (await _abpStrictRedirectUriValidator.IsPostLogoutRedirectUriValidAsync("https://api.t1.abp:8080/", _testClient)).ShouldBeFalse(); (await _abpStrictRedirectUriValidator.IsPostLogoutRedirectUriValidAsync("http://ng.t1.abp.io", _testClient)).ShouldBeFalse(); + (await _abpStrictRedirectUriValidator.IsPostLogoutRedirectUriValidAsync("http://t1.ng.abp.io/index.html.mydomain.com", _testClient)).ShouldBeFalse(); } } } diff --git a/modules/identityserver/test/Volo.Abp.IdentityServer.Domain.Tests/Volo/Abp/IdentityServer/AbpWildcardSubdomainCorsPolicyService_Tests.cs b/modules/identityserver/test/Volo.Abp.IdentityServer.Domain.Tests/Volo/Abp/IdentityServer/AbpWildcardSubdomainCorsPolicyService_Tests.cs index fcb8e756e0..36949582d7 100644 --- a/modules/identityserver/test/Volo.Abp.IdentityServer.Domain.Tests/Volo/Abp/IdentityServer/AbpWildcardSubdomainCorsPolicyService_Tests.cs +++ b/modules/identityserver/test/Volo.Abp.IdentityServer.Domain.Tests/Volo/Abp/IdentityServer/AbpWildcardSubdomainCorsPolicyService_Tests.cs @@ -35,6 +35,8 @@ namespace Volo.Abp.IdentityServer (await _corsPolicyService.IsOriginAllowedAsync("https://abp.io")).ShouldBeTrue(); (await _corsPolicyService.IsOriginAllowedAsync("https://t1.abp.io")).ShouldBeTrue(); (await _corsPolicyService.IsOriginAllowedAsync("https://t1.ng.abp.io")).ShouldBeTrue(); + + (await _corsPolicyService.IsOriginAllowedAsync("https://t1.abp.io.mydomain.com")).ShouldBeFalse(); } } } diff --git a/modules/identityserver/test/Volo.Abp.IdentityServer.EntityFrameworkCore.Tests/Volo.Abp.IdentityServer.EntityFrameworkCore.Tests.abppkg.json b/modules/identityserver/test/Volo.Abp.IdentityServer.EntityFrameworkCore.Tests/Volo.Abp.IdentityServer.EntityFrameworkCore.Tests.abppkg.json new file mode 100644 index 0000000000..a686451fbc --- /dev/null +++ b/modules/identityserver/test/Volo.Abp.IdentityServer.EntityFrameworkCore.Tests/Volo.Abp.IdentityServer.EntityFrameworkCore.Tests.abppkg.json @@ -0,0 +1,3 @@ +{ + "role": "lib.test" +} \ No newline at end of file diff --git a/modules/identityserver/test/Volo.Abp.IdentityServer.MongoDB.Tests/Volo.Abp.IdentityServer.MongoDB.Tests.abppkg.json b/modules/identityserver/test/Volo.Abp.IdentityServer.MongoDB.Tests/Volo.Abp.IdentityServer.MongoDB.Tests.abppkg.json new file mode 100644 index 0000000000..a686451fbc --- /dev/null +++ b/modules/identityserver/test/Volo.Abp.IdentityServer.MongoDB.Tests/Volo.Abp.IdentityServer.MongoDB.Tests.abppkg.json @@ -0,0 +1,3 @@ +{ + "role": "lib.test" +} \ No newline at end of file diff --git a/modules/identityserver/test/Volo.Abp.IdentityServer.TestBase/Volo.Abp.IdentityServer.TestBase.abppkg.json b/modules/identityserver/test/Volo.Abp.IdentityServer.TestBase/Volo.Abp.IdentityServer.TestBase.abppkg.json new file mode 100644 index 0000000000..9e26dfeeb6 --- /dev/null +++ b/modules/identityserver/test/Volo.Abp.IdentityServer.TestBase/Volo.Abp.IdentityServer.TestBase.abppkg.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/modules/permission-management/Volo.Abp.PermissionManagement.abpmdl.json b/modules/permission-management/Volo.Abp.PermissionManagement.abpmdl.json index b0c0b4ebb7..82dc87dade 100644 --- a/modules/permission-management/Volo.Abp.PermissionManagement.abpmdl.json +++ b/modules/permission-management/Volo.Abp.PermissionManagement.abpmdl.json @@ -1,127 +1,78 @@ { "folders": { - "src": {}, - "test": {} + "items": { + "src": {}, + "test": {} + } }, "packages": { "Volo.Abp.PermissionManagement.Domain.Shared": { - "path": "src/Volo.Abp.PermissionManagement.Domain.Shared/Volo.Abp.PermissionManagement.Domain.Shared.csproj", - "folder": "src", - "includes": { - "lib.domain.shared": {} - } + "path": "src/Volo.Abp.PermissionManagement.Domain.Shared/Volo.Abp.PermissionManagement.Domain.Shared.abppkg.json", + "folder": "src" }, "Volo.Abp.PermissionManagement.Domain": { - "path": "src/Volo.Abp.PermissionManagement.Domain/Volo.Abp.PermissionManagement.Domain.csproj", - "folder": "src", - "includes": { - "lib.domain": {} - } + "path": "src/Volo.Abp.PermissionManagement.Domain/Volo.Abp.PermissionManagement.Domain.abppkg.json", + "folder": "src" }, "Volo.Abp.PermissionManagement.Application.Contracts": { - "path": "src/Volo.Abp.PermissionManagement.Application.Contracts/Volo.Abp.PermissionManagement.Application.Contracts.csproj", - "folder": "src", - "includes": { - "lib.application.contracts": {} - } + "path": "src/Volo.Abp.PermissionManagement.Application.Contracts/Volo.Abp.PermissionManagement.Application.Contracts.abppkg.json", + "folder": "src" }, "Volo.Abp.PermissionManagement.Application": { - "path": "src/Volo.Abp.PermissionManagement.Application/Volo.Abp.PermissionManagement.Application.csproj", - "folder": "src", - "includes": { - "lib.application": {} - } + "path": "src/Volo.Abp.PermissionManagement.Application/Volo.Abp.PermissionManagement.Application.abppkg.json", + "folder": "src" }, "Volo.Abp.PermissionManagement.EntityFrameworkCore": { - "path": "src/Volo.Abp.PermissionManagement.EntityFrameworkCore/Volo.Abp.PermissionManagement.EntityFrameworkCore.csproj", - "folder": "src", - "includes": { - "lib.ef": {} - } + "path": "src/Volo.Abp.PermissionManagement.EntityFrameworkCore/Volo.Abp.PermissionManagement.EntityFrameworkCore.abppkg.json", + "folder": "src" + }, + "Volo.Abp.PermissionManagement.Web": { + "path": "src/Volo.Abp.PermissionManagement.Web/Volo.Abp.PermissionManagement.Web.abppkg.json", + "folder": "src" + }, + "Volo.Abp.PermissionManagement.Domain.Tests": { + "path": "test/Volo.Abp.PermissionManagement.Domain.Tests/Volo.Abp.PermissionManagement.Domain.Tests.abppkg.json", + "folder": "test" + }, + "Volo.Abp.PermissionManagement.TestBase": { + "path": "test/Volo.Abp.PermissionManagement.TestBase/Volo.Abp.PermissionManagement.TestBase.abppkg.json", + "folder": "test" + }, + "Volo.Abp.PermissionManagement.EntityFrameworkCore.Tests": { + "path": "test/Volo.Abp.PermissionManagement.EntityFrameworkCore.Tests/Volo.Abp.PermissionManagement.EntityFrameworkCore.Tests.abppkg.json", + "folder": "test" }, "Volo.Abp.PermissionManagement.MongoDB": { - "path": "src/Volo.Abp.PermissionManagement.MongoDB/Volo.Abp.PermissionManagement.MongoDB.csproj", - "folder": "src", - "includes": { - "lib.mongodb": {} - } + "path": "src/Volo.Abp.PermissionManagement.MongoDB/Volo.Abp.PermissionManagement.MongoDB.abppkg.json", + "folder": "src" + }, + "Volo.Abp.PermissionManagement.MongoDB.Tests": { + "path": "test/Volo.Abp.PermissionManagement.MongoDB.Tests/Volo.Abp.PermissionManagement.MongoDB.Tests.abppkg.json", + "folder": "test" }, "Volo.Abp.PermissionManagement.HttpApi": { - "path": "src/Volo.Abp.PermissionManagement.HttpApi/Volo.Abp.PermissionManagement.HttpApi.csproj", - "folder": "src", - "includes": { - "lib.http-api": {} - } + "path": "src/Volo.Abp.PermissionManagement.HttpApi/Volo.Abp.PermissionManagement.HttpApi.abppkg.json", + "folder": "src" }, "Volo.Abp.PermissionManagement.HttpApi.Client": { - "path": "src/Volo.Abp.PermissionManagement.HttpApi.Client/Volo.Abp.PermissionManagement.HttpApi.Client.csproj", - "folder": "src", - "includes": { - "lib.http-api-client": {} - } + "path": "src/Volo.Abp.PermissionManagement.HttpApi.Client/Volo.Abp.PermissionManagement.HttpApi.Client.abppkg.json", + "folder": "src" }, - "Volo.Abp.PermissionManagement.Web": { - "path": "src/Volo.Abp.PermissionManagement.Web/Volo.Abp.PermissionManagement.Web.csproj", - "folder": "src", - "includes": { - "lib.ui.mvc": {} - } + "Volo.Abp.PermissionManagement.Application.Tests": { + "path": "test/Volo.Abp.PermissionManagement.Application.Tests/Volo.Abp.PermissionManagement.Application.Tests.abppkg.json", + "folder": "test" }, "Volo.Abp.PermissionManagement.Blazor": { - "path": "src/Volo.Abp.PermissionManagement.Blazor/Volo.Abp.PermissionManagement.Blazor.csproj", - "folder": "src", - "includes": { - "lib.ui.blazor": {} - } + "path": "src/Volo.Abp.PermissionManagement.Blazor/Volo.Abp.PermissionManagement.Blazor.abppkg.json", + "folder": "src" }, "Volo.Abp.PermissionManagement.Blazor.Server": { - "path": "src/Volo.Abp.PermissionManagement.Blazor.Server/Volo.Abp.PermissionManagement.Blazor.Server.csproj", - "folder": "src", - "includes": { - "lib.ui.blazor-server": {} - } + "path": "src/Volo.Abp.PermissionManagement.Blazor.Server/Volo.Abp.PermissionManagement.Blazor.Server.abppkg.json", + "folder": "src" }, "Volo.Abp.PermissionManagement.Blazor.WebAssembly": { - "path": "src/Volo.Abp.PermissionManagement.Blazor.WebAssembly/Volo.Abp.PermissionManagement.Blazor.WebAssembly.csproj", - "folder": "src", - "includes": { - "lib.ui.blazor-wasm": {} - } - }, - "Volo.Abp.PermissionManagement.TestBase": { - "path": "test/Volo.Abp.PermissionManagement.TestBase/Volo.Abp.PermissionManagement.TestBase.csproj", - "folder": "test", - "includes": { - "lib.test": {} - } - }, - "Volo.Abp.PermissionManagement.Domain.Tests": { - "path": "test/Volo.Abp.PermissionManagement.Domain.Tests/Volo.Abp.PermissionManagement.Domain.Tests.csproj", - "folder": "test", - "includes": { - "lib.test": {} - } - }, - "Volo.Abp.PermissionManagement.EntityFrameworkCore.Tests": { - "path": "test/Volo.Abp.PermissionManagement.EntityFrameworkCore.Tests/Volo.Abp.PermissionManagement.EntityFrameworkCore.Tests.csproj", - "folder": "test", - "includes": { - "lib.test": {} - } - }, - "Volo.Abp.PermissionManagement.MongoDB.Tests": { - "path": "test/Volo.Abp.PermissionManagement.MongoDB.Tests/Volo.Abp.PermissionManagement.MongoDB.Tests.csproj", - "folder": "test", - "includes": { - "lib.test": {} - } - }, - "Volo.Abp.PermissionManagement.Application.Tests": { - "path": "test/Volo.Abp.PermissionManagement.Application.Tests/Volo.Abp.PermissionManagement.Application.Tests.csproj", - "folder": "test", - "includes": { - "lib.test": {} - } + "path": "src/Volo.Abp.PermissionManagement.Blazor.WebAssembly/Volo.Abp.PermissionManagement.Blazor.WebAssembly.abppkg.json", + "folder": "src" } } } \ No newline at end of file diff --git a/modules/permission-management/src/Volo.Abp.PermissionManagement.Application.Contracts/Volo.Abp.PermissionManagement.Application.Contracts.abppkg.json b/modules/permission-management/src/Volo.Abp.PermissionManagement.Application.Contracts/Volo.Abp.PermissionManagement.Application.Contracts.abppkg.json new file mode 100644 index 0000000000..49032794e2 --- /dev/null +++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.Application.Contracts/Volo.Abp.PermissionManagement.Application.Contracts.abppkg.json @@ -0,0 +1,3 @@ +{ + "role": "lib.application-contracts" +} \ No newline at end of file diff --git a/modules/permission-management/src/Volo.Abp.PermissionManagement.Application/Volo.Abp.PermissionManagement.Application.abppkg.json b/modules/permission-management/src/Volo.Abp.PermissionManagement.Application/Volo.Abp.PermissionManagement.Application.abppkg.json new file mode 100644 index 0000000000..412567ac33 --- /dev/null +++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.Application/Volo.Abp.PermissionManagement.Application.abppkg.json @@ -0,0 +1,3 @@ +{ + "role": "lib.application" +} \ No newline at end of file diff --git a/modules/permission-management/src/Volo.Abp.PermissionManagement.Application/Volo/Abp/PermissionManagement/PermissionAppService.cs b/modules/permission-management/src/Volo.Abp.PermissionManagement.Application/Volo/Abp/PermissionManagement/PermissionAppService.cs index 4bc73a6f86..abcbcd6a48 100644 --- a/modules/permission-management/src/Volo.Abp.PermissionManagement.Application/Volo/Abp/PermissionManagement/PermissionAppService.cs +++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.Application/Volo/Abp/PermissionManagement/PermissionAppService.cs @@ -7,6 +7,7 @@ using Microsoft.Extensions.Options; using Volo.Abp.Application.Services; using Volo.Abp.Authorization.Permissions; using Volo.Abp.MultiTenancy; +using Volo.Abp.SimpleStateChecking; namespace Volo.Abp.PermissionManagement { @@ -16,18 +17,18 @@ namespace Volo.Abp.PermissionManagement protected PermissionManagementOptions Options { get; } protected IPermissionManager PermissionManager { get; } protected IPermissionDefinitionManager PermissionDefinitionManager { get; } - protected IPermissionStateManager PermissionStateManager { get; } + protected ISimpleStateCheckerManager SimpleStateCheckerManager { get; } public PermissionAppService( IPermissionManager permissionManager, IPermissionDefinitionManager permissionDefinitionManager, IOptions options, - IPermissionStateManager permissionStateManager) + ISimpleStateCheckerManager simpleStateCheckerManager) { Options = options.Value; PermissionManager = permissionManager; PermissionDefinitionManager = permissionDefinitionManager; - PermissionStateManager = permissionStateManager; + SimpleStateCheckerManager = simpleStateCheckerManager; } public virtual async Task GetAsync(string providerName, string providerKey) @@ -58,7 +59,7 @@ namespace Volo.Abp.PermissionManagement continue; } - if (!await PermissionStateManager.IsEnabledAsync(permission)) + if (!await SimpleStateCheckerManager.IsEnabledAsync(permission)) { continue; } diff --git a/modules/permission-management/src/Volo.Abp.PermissionManagement.Blazor.Server/Volo.Abp.PermissionManagement.Blazor.Server.abppkg.json b/modules/permission-management/src/Volo.Abp.PermissionManagement.Blazor.Server/Volo.Abp.PermissionManagement.Blazor.Server.abppkg.json new file mode 100644 index 0000000000..ef40d81585 --- /dev/null +++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.Blazor.Server/Volo.Abp.PermissionManagement.Blazor.Server.abppkg.json @@ -0,0 +1,3 @@ +{ + "role": "lib.blazor-server" +} \ No newline at end of file diff --git a/modules/permission-management/src/Volo.Abp.PermissionManagement.Blazor.WebAssembly/Volo.Abp.PermissionManagement.Blazor.WebAssembly.abppkg.json b/modules/permission-management/src/Volo.Abp.PermissionManagement.Blazor.WebAssembly/Volo.Abp.PermissionManagement.Blazor.WebAssembly.abppkg.json new file mode 100644 index 0000000000..471ef5e067 --- /dev/null +++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.Blazor.WebAssembly/Volo.Abp.PermissionManagement.Blazor.WebAssembly.abppkg.json @@ -0,0 +1,3 @@ +{ + "role": "lib.blazor-wasm" +} \ No newline at end of file diff --git a/modules/permission-management/src/Volo.Abp.PermissionManagement.Blazor/Volo.Abp.PermissionManagement.Blazor.abppkg.json b/modules/permission-management/src/Volo.Abp.PermissionManagement.Blazor/Volo.Abp.PermissionManagement.Blazor.abppkg.json new file mode 100644 index 0000000000..19c29b7b8b --- /dev/null +++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.Blazor/Volo.Abp.PermissionManagement.Blazor.abppkg.json @@ -0,0 +1,3 @@ +{ + "role": "lib.blazor" +} \ No newline at end of file diff --git a/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain.Shared/Volo.Abp.PermissionManagement.Domain.Shared.abppkg.json b/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain.Shared/Volo.Abp.PermissionManagement.Domain.Shared.abppkg.json new file mode 100644 index 0000000000..8b3de05f76 --- /dev/null +++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain.Shared/Volo.Abp.PermissionManagement.Domain.Shared.abppkg.json @@ -0,0 +1,3 @@ +{ + "role": "lib.domain-shared" +} \ No newline at end of file diff --git a/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain.Shared/Volo/Abp/PermissionManagement/Localization/Domain/hi.json b/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain.Shared/Volo/Abp/PermissionManagement/Localization/Domain/hi.json new file mode 100644 index 0000000000..308278d307 --- /dev/null +++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain.Shared/Volo/Abp/PermissionManagement/Localization/Domain/hi.json @@ -0,0 +1,10 @@ +{ + "culture": "hi", + "texts": { + "Permissions": "अनुमतियां", + "OnlyProviderPermissons": "केवल यह प्रदाता", + "All": "सब", + "SelectAllInAllTabs": "सभी अनुमतियां प्रदान करें", + "SelectAllInThisTab": "सभी का चयन करे" + } +} \ No newline at end of file diff --git a/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain.Shared/Volo/Abp/PermissionManagement/Localization/Domain/it.json b/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain.Shared/Volo/Abp/PermissionManagement/Localization/Domain/it.json new file mode 100644 index 0000000000..9e1bba1728 --- /dev/null +++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain.Shared/Volo/Abp/PermissionManagement/Localization/Domain/it.json @@ -0,0 +1,10 @@ +{ + "culture": "it", + "texts": { + "Permissions": "Autorizzazioni", + "OnlyProviderPermissons": "Solo questo provider", + "All": "Tutti", + "SelectAllInAllTabs": "Concedi tutte le autorizzazioni", + "SelectAllInThisTab": "Seleziona tutto" + } +} \ No newline at end of file diff --git a/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain/Volo.Abp.PermissionManagement.Domain.abppkg.json b/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain/Volo.Abp.PermissionManagement.Domain.abppkg.json new file mode 100644 index 0000000000..1d574efe45 --- /dev/null +++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain/Volo.Abp.PermissionManagement.Domain.abppkg.json @@ -0,0 +1,3 @@ +{ + "role": "lib.domain" +} \ No newline at end of file diff --git a/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain/Volo/Abp/PermissionManagement/PermissionManager.cs b/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain/Volo/Abp/PermissionManagement/PermissionManager.cs index c178a6ae0e..d0ee7c4853 100644 --- a/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain/Volo/Abp/PermissionManagement/PermissionManager.cs +++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain/Volo/Abp/PermissionManagement/PermissionManager.cs @@ -9,6 +9,7 @@ using Volo.Abp.Caching; using Volo.Abp.DependencyInjection; using Volo.Abp.Guids; using Volo.Abp.MultiTenancy; +using Volo.Abp.SimpleStateChecking; namespace Volo.Abp.PermissionManagement { @@ -18,7 +19,7 @@ namespace Volo.Abp.PermissionManagement protected IPermissionDefinitionManager PermissionDefinitionManager { get; } - protected IPermissionStateManager PermissionStateManager { get; } + protected ISimpleStateCheckerManager SimpleStateCheckerManager { get; } protected IGuidGenerator GuidGenerator { get; } @@ -34,7 +35,7 @@ namespace Volo.Abp.PermissionManagement public PermissionManager( IPermissionDefinitionManager permissionDefinitionManager, - IPermissionStateManager permissionStateManager, + ISimpleStateCheckerManager simpleStateCheckerManager, IPermissionGrantRepository permissionGrantRepository, IServiceProvider serviceProvider, IGuidGenerator guidGenerator, @@ -45,7 +46,7 @@ namespace Volo.Abp.PermissionManagement GuidGenerator = guidGenerator; CurrentTenant = currentTenant; Cache = cache; - PermissionStateManager = permissionStateManager; + SimpleStateCheckerManager = simpleStateCheckerManager; PermissionGrantRepository = permissionGrantRepository; PermissionDefinitionManager = permissionDefinitionManager; Options = options.Value; @@ -80,7 +81,7 @@ namespace Volo.Abp.PermissionManagement { var permission = PermissionDefinitionManager.Get(permissionName); - if (!permission.IsEnabled || !await PermissionStateManager.IsEnabledAsync(permission)) + if (!permission.IsEnabled || !await SimpleStateCheckerManager.IsEnabledAsync(permission)) { //TODO: BusinessException throw new ApplicationException($"The permission named '{permission.Name}' is disabled!"); @@ -150,7 +151,7 @@ namespace Volo.Abp.PermissionManagement return result; } - if (!await PermissionStateManager.IsEnabledAsync(permission)) + if (!await SimpleStateCheckerManager.IsEnabledAsync(permission)) { return result; } diff --git a/modules/permission-management/src/Volo.Abp.PermissionManagement.EntityFrameworkCore/Volo.Abp.PermissionManagement.EntityFrameworkCore.abppkg.json b/modules/permission-management/src/Volo.Abp.PermissionManagement.EntityFrameworkCore/Volo.Abp.PermissionManagement.EntityFrameworkCore.abppkg.json new file mode 100644 index 0000000000..e1c64f0175 --- /dev/null +++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.EntityFrameworkCore/Volo.Abp.PermissionManagement.EntityFrameworkCore.abppkg.json @@ -0,0 +1,3 @@ +{ + "role": "lib.ef" +} \ No newline at end of file diff --git a/modules/permission-management/src/Volo.Abp.PermissionManagement.HttpApi.Client/Volo.Abp.PermissionManagement.HttpApi.Client.abppkg.json b/modules/permission-management/src/Volo.Abp.PermissionManagement.HttpApi.Client/Volo.Abp.PermissionManagement.HttpApi.Client.abppkg.json new file mode 100644 index 0000000000..7deef5e383 --- /dev/null +++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.HttpApi.Client/Volo.Abp.PermissionManagement.HttpApi.Client.abppkg.json @@ -0,0 +1,3 @@ +{ + "role": "lib.http-api-client" +} \ No newline at end of file diff --git a/modules/permission-management/src/Volo.Abp.PermissionManagement.HttpApi/Volo.Abp.PermissionManagement.HttpApi.abppkg.json b/modules/permission-management/src/Volo.Abp.PermissionManagement.HttpApi/Volo.Abp.PermissionManagement.HttpApi.abppkg.json new file mode 100644 index 0000000000..515bfe64c4 --- /dev/null +++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.HttpApi/Volo.Abp.PermissionManagement.HttpApi.abppkg.json @@ -0,0 +1,3 @@ +{ + "role": "lib.http-api" +} \ No newline at end of file diff --git a/modules/permission-management/src/Volo.Abp.PermissionManagement.MongoDB/Volo.Abp.PermissionManagement.MongoDB.abppkg.json b/modules/permission-management/src/Volo.Abp.PermissionManagement.MongoDB/Volo.Abp.PermissionManagement.MongoDB.abppkg.json new file mode 100644 index 0000000000..8b23fd1e69 --- /dev/null +++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.MongoDB/Volo.Abp.PermissionManagement.MongoDB.abppkg.json @@ -0,0 +1,3 @@ +{ + "role": "lib.mongodb" +} \ No newline at end of file diff --git a/modules/permission-management/src/Volo.Abp.PermissionManagement.Web/Volo.Abp.PermissionManagement.Web.abppkg.json b/modules/permission-management/src/Volo.Abp.PermissionManagement.Web/Volo.Abp.PermissionManagement.Web.abppkg.json new file mode 100644 index 0000000000..930c4018b3 --- /dev/null +++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.Web/Volo.Abp.PermissionManagement.Web.abppkg.json @@ -0,0 +1,3 @@ +{ + "role": "lib.mvc" +} \ No newline at end of file diff --git a/modules/permission-management/test/Volo.Abp.PermissionManagement.Application.Tests/Volo.Abp.PermissionManagement.Application.Tests.abppkg.json b/modules/permission-management/test/Volo.Abp.PermissionManagement.Application.Tests/Volo.Abp.PermissionManagement.Application.Tests.abppkg.json new file mode 100644 index 0000000000..a686451fbc --- /dev/null +++ b/modules/permission-management/test/Volo.Abp.PermissionManagement.Application.Tests/Volo.Abp.PermissionManagement.Application.Tests.abppkg.json @@ -0,0 +1,3 @@ +{ + "role": "lib.test" +} \ No newline at end of file diff --git a/modules/permission-management/test/Volo.Abp.PermissionManagement.Domain.Tests/Volo.Abp.PermissionManagement.Domain.Tests.abppkg.json b/modules/permission-management/test/Volo.Abp.PermissionManagement.Domain.Tests/Volo.Abp.PermissionManagement.Domain.Tests.abppkg.json new file mode 100644 index 0000000000..a686451fbc --- /dev/null +++ b/modules/permission-management/test/Volo.Abp.PermissionManagement.Domain.Tests/Volo.Abp.PermissionManagement.Domain.Tests.abppkg.json @@ -0,0 +1,3 @@ +{ + "role": "lib.test" +} \ No newline at end of file diff --git a/modules/permission-management/test/Volo.Abp.PermissionManagement.EntityFrameworkCore.Tests/Volo.Abp.PermissionManagement.EntityFrameworkCore.Tests.abppkg.json b/modules/permission-management/test/Volo.Abp.PermissionManagement.EntityFrameworkCore.Tests/Volo.Abp.PermissionManagement.EntityFrameworkCore.Tests.abppkg.json new file mode 100644 index 0000000000..a686451fbc --- /dev/null +++ b/modules/permission-management/test/Volo.Abp.PermissionManagement.EntityFrameworkCore.Tests/Volo.Abp.PermissionManagement.EntityFrameworkCore.Tests.abppkg.json @@ -0,0 +1,3 @@ +{ + "role": "lib.test" +} \ No newline at end of file diff --git a/modules/permission-management/test/Volo.Abp.PermissionManagement.MongoDB.Tests/Volo.Abp.PermissionManagement.MongoDB.Tests.abppkg.json b/modules/permission-management/test/Volo.Abp.PermissionManagement.MongoDB.Tests/Volo.Abp.PermissionManagement.MongoDB.Tests.abppkg.json new file mode 100644 index 0000000000..a686451fbc --- /dev/null +++ b/modules/permission-management/test/Volo.Abp.PermissionManagement.MongoDB.Tests/Volo.Abp.PermissionManagement.MongoDB.Tests.abppkg.json @@ -0,0 +1,3 @@ +{ + "role": "lib.test" +} \ No newline at end of file diff --git a/modules/permission-management/test/Volo.Abp.PermissionManagement.TestBase/Volo.Abp.PermissionManagement.TestBase.abppkg.json b/modules/permission-management/test/Volo.Abp.PermissionManagement.TestBase/Volo.Abp.PermissionManagement.TestBase.abppkg.json new file mode 100644 index 0000000000..9e26dfeeb6 --- /dev/null +++ b/modules/permission-management/test/Volo.Abp.PermissionManagement.TestBase/Volo.Abp.PermissionManagement.TestBase.abppkg.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/modules/permission-management/test/Volo.Abp.PermissionManagement.TestBase/Volo/Abp/PermissionManagement/TestPermissionDefinitionProvider.cs b/modules/permission-management/test/Volo.Abp.PermissionManagement.TestBase/Volo/Abp/PermissionManagement/TestPermissionDefinitionProvider.cs index d2256a5868..f01961d24c 100644 --- a/modules/permission-management/test/Volo.Abp.PermissionManagement.TestBase/Volo/Abp/PermissionManagement/TestPermissionDefinitionProvider.cs +++ b/modules/permission-management/test/Volo.Abp.PermissionManagement.TestBase/Volo/Abp/PermissionManagement/TestPermissionDefinitionProvider.cs @@ -19,7 +19,7 @@ namespace Volo.Abp.PermissionManagement testGroup.AddPermission("MyPermission4", multiTenancySide: MultiTenancySides.Host).WithProviders(UserPermissionValueProvider.ProviderName); - testGroup.AddPermission("MyPermission5").AddStateProviders(new TestRequireRolePermissionStateProvider("super-admin")); + testGroup.AddPermission("MyPermission5").StateCheckers.Add(new TestRequireRolePermissionStateProvider("super-admin")); } } } diff --git a/modules/permission-management/test/Volo.Abp.PermissionManagement.TestBase/Volo/Abp/PermissionManagement/TestRequireRolePermissionStateProvider.cs b/modules/permission-management/test/Volo.Abp.PermissionManagement.TestBase/Volo/Abp/PermissionManagement/TestRequireRolePermissionStateProvider.cs index 56e34f2894..3531479b43 100644 --- a/modules/permission-management/test/Volo.Abp.PermissionManagement.TestBase/Volo/Abp/PermissionManagement/TestRequireRolePermissionStateProvider.cs +++ b/modules/permission-management/test/Volo.Abp.PermissionManagement.TestBase/Volo/Abp/PermissionManagement/TestRequireRolePermissionStateProvider.cs @@ -4,10 +4,11 @@ using System.Threading.Tasks; using Microsoft.Extensions.DependencyInjection; using Volo.Abp.Authorization.Permissions; using Volo.Abp.Security.Claims; +using Volo.Abp.SimpleStateChecking; namespace Volo.Abp.PermissionManagement { - public class TestRequireRolePermissionStateProvider : IPermissionStateProvider + public class TestRequireRolePermissionStateProvider : ISimpleStateChecker { private readonly List _allowRoles = new List(); @@ -16,7 +17,7 @@ namespace Volo.Abp.PermissionManagement _allowRoles.AddRange(roles); } - public Task IsEnabledAsync(PermissionStateContext context) + public Task IsEnabledAsync(SimpleStateCheckerContext context) { var currentPrincipalAccessor = context.ServiceProvider.GetRequiredService(); return Task.FromResult(currentPrincipalAccessor.Principal != null && _allowRoles.Any(role => currentPrincipalAccessor.Principal.IsInRole(role))); diff --git a/modules/setting-management/Volo.Abp.SettingManagement.abpmdl.json b/modules/setting-management/Volo.Abp.SettingManagement.abpmdl.json index 8181f78b91..899d1a00ed 100644 --- a/modules/setting-management/Volo.Abp.SettingManagement.abpmdl.json +++ b/modules/setting-management/Volo.Abp.SettingManagement.abpmdl.json @@ -1,120 +1,79 @@ { "folders": { - "src": {}, - "test": {} + "items": { + "src": {}, + "test": {}, + "app": {} + } }, "packages": { "Volo.Abp.SettingManagement.Domain.Shared": { - "path": "src/Volo.Abp.SettingManagement.Domain.Shared/Volo.Abp.SettingManagement.Domain.Shared.csproj", - "folder": "src", - "includes": { - "lib.domain.shared": {} - } + "path": "src/Volo.Abp.SettingManagement.Domain.Shared/Volo.Abp.SettingManagement.Domain.Shared.abppkg.json", + "folder": "src" }, "Volo.Abp.SettingManagement.Domain": { - "path": "src/Volo.Abp.SettingManagement.Domain/Volo.Abp.SettingManagement.Domain.csproj", - "folder": "src", - "includes": { - "lib.domain": {} - } - }, - "Volo.Abp.SettingManagement.Application.Contracts": { - "path": "src/Volo.Abp.SettingManagement.Application.Contracts/Volo.Abp.SettingManagement.Application.Contracts.csproj", - "folder": "src", - "includes": { - "lib.application.contracts": {} - } - }, - "Volo.Abp.SettingManagement.Application": { - "path": "src/Volo.Abp.SettingManagement.Application/Volo.Abp.SettingManagement.Application.csproj", - "folder": "src", - "includes": { - "lib.application": {} - } + "path": "src/Volo.Abp.SettingManagement.Domain/Volo.Abp.SettingManagement.Domain.abppkg.json", + "folder": "src" }, "Volo.Abp.SettingManagement.EntityFrameworkCore": { - "path": "src/Volo.Abp.SettingManagement.EntityFrameworkCore/Volo.Abp.SettingManagement.EntityFrameworkCore.csproj", - "folder": "src", - "includes": { - "lib.ef": {} - } + "path": "src/Volo.Abp.SettingManagement.EntityFrameworkCore/Volo.Abp.SettingManagement.EntityFrameworkCore.abppkg.json", + "folder": "src" + }, + "Volo.Abp.SettingManagement.Tests": { + "path": "test/Volo.Abp.SettingManagement.Tests/Volo.Abp.SettingManagement.Tests.abppkg.json", + "folder": "test" }, "Volo.Abp.SettingManagement.MongoDB": { - "path": "src/Volo.Abp.SettingManagement.MongoDB/Volo.Abp.SettingManagement.MongoDB.csproj", - "folder": "src", - "includes": { - "lib.mongodb": {} - } + "path": "src/Volo.Abp.SettingManagement.MongoDB/Volo.Abp.SettingManagement.MongoDB.abppkg.json", + "folder": "src" }, - "Volo.Abp.SettingManagement.HttpApi": { - "path": "src/Volo.Abp.SettingManagement.HttpApi/Volo.Abp.SettingManagement.HttpApi.csproj", - "folder": "src", - "includes": { - "lib.http-api": {} - } + "Volo.Abp.SettingManagement.TestBase": { + "path": "test/Volo.Abp.SettingManagement.TestBase/Volo.Abp.SettingManagement.TestBase.abppkg.json", + "folder": "test" }, - "Volo.Abp.SettingManagement.HttpApi.Client": { - "path": "src/Volo.Abp.SettingManagement.HttpApi.Client/Volo.Abp.SettingManagement.HttpApi.Client.csproj", - "folder": "src", - "includes": { - "lib.http-api-client": {} - } + "Volo.Abp.SettingManagement.EntityFrameworkCore.Tests": { + "path": "test/Volo.Abp.SettingManagement.EntityFrameworkCore.Tests/Volo.Abp.SettingManagement.EntityFrameworkCore.Tests.abppkg.json", + "folder": "test" + }, + "Volo.Abp.SettingManagement.MongoDB.Tests": { + "path": "test/Volo.Abp.SettingManagement.MongoDB.Tests/Volo.Abp.SettingManagement.MongoDB.Tests.abppkg.json", + "folder": "test" }, "Volo.Abp.SettingManagement.Web": { - "path": "src/Volo.Abp.SettingManagement.Web/Volo.Abp.SettingManagement.Web.csproj", - "folder": "src", - "includes": { - "lib.ui.mvc": {} - } + "path": "src/Volo.Abp.SettingManagement.Web/Volo.Abp.SettingManagement.Web.abppkg.json", + "folder": "src" }, "Volo.Abp.SettingManagement.Blazor": { - "path": "src/Volo.Abp.SettingManagement.Blazor/Volo.Abp.SettingManagement.Blazor.csproj", - "folder": "src", - "includes": { - "lib.ui.blazor": {} - } + "path": "src/Volo.Abp.SettingManagement.Blazor/Volo.Abp.SettingManagement.Blazor.abppkg.json", + "folder": "src" }, - "Volo.Abp.SettingManagement.Blazor.Server": { - "path": "src/Volo.Abp.SettingManagement.Blazor.Server/Volo.Abp.SettingManagement.Blazor.Server.csproj", - "folder": "src", - "includes": { - "lib.ui.blazor-server": {} - } + "Volo.Abp.SettingManagement.Application": { + "path": "src/Volo.Abp.SettingManagement.Application/Volo.Abp.SettingManagement.Application.abppkg.json", + "folder": "src" }, - "Volo.Abp.SettingManagement.Blazor.WebAssembly": { - "path": "src/Volo.Abp.SettingManagement.Blazor.WebAssembly/Volo.Abp.SettingManagement.Blazor.WebAssembly.csproj", - "folder": "src", - "includes": { - "lib.ui.blazor-wasm": {} - } + "Volo.Abp.SettingManagement.Application.Contracts": { + "path": "src/Volo.Abp.SettingManagement.Application.Contracts/Volo.Abp.SettingManagement.Application.Contracts.abppkg.json", + "folder": "src" }, - "Volo.Abp.SettingManagement.TestBase": { - "path": "test/Volo.Abp.SettingManagement.TestBase/Volo.Abp.SettingManagement.TestBase.csproj", - "folder": "test", - "includes": { - "lib.test": {} - } + "Volo.Abp.SettingManagement.HttpApi": { + "path": "src/Volo.Abp.SettingManagement.HttpApi/Volo.Abp.SettingManagement.HttpApi.abppkg.json", + "folder": "src" }, - "Volo.Abp.SettingManagement.Tests": { - "path": "test/Volo.Abp.SettingManagement.Tests/Volo.Abp.SettingManagement.Tests.csproj", - "folder": "test", - "includes": { - "lib.test": {} - } + "Volo.Abp.SettingManagement.HttpApi.Client": { + "path": "src/Volo.Abp.SettingManagement.HttpApi.Client/Volo.Abp.SettingManagement.HttpApi.Client.abppkg.json", + "folder": "src" }, - "Volo.Abp.SettingManagement.EntityFrameworkCore.Tests": { - "path": "test/Volo.Abp.SettingManagement.EntityFrameworkCore.Tests/Volo.Abp.SettingManagement.EntityFrameworkCore.Tests.csproj", - "folder": "test", - "includes": { - "lib.test": {} - } + "Volo.Abp.SettingManagement.DemoApp": { + "path": "app/Volo.Abp.SettingManagement.DemoApp/Volo.Abp.SettingManagement.DemoApp.abppkg.json", + "folder": "app" }, - "Volo.Abp.SettingManagement.MongoDB.Tests": { - "path": "test/Volo.Abp.SettingManagement.MongoDB.Tests/Volo.Abp.SettingManagement.MongoDB.Tests.csproj", - "folder": "test", - "includes": { - "lib.test": {} - } + "Volo.Abp.SettingManagement.Blazor.Server": { + "path": "src/Volo.Abp.SettingManagement.Blazor.Server/Volo.Abp.SettingManagement.Blazor.Server.abppkg.json", + "folder": "src" + }, + "Volo.Abp.SettingManagement.Blazor.WebAssembly": { + "path": "src/Volo.Abp.SettingManagement.Blazor.WebAssembly/Volo.Abp.SettingManagement.Blazor.WebAssembly.abppkg.json", + "folder": "src" } } } \ No newline at end of file diff --git a/modules/setting-management/app/Volo.Abp.SettingManagement.DemoApp/DemoAppModule.cs b/modules/setting-management/app/Volo.Abp.SettingManagement.DemoApp/DemoAppModule.cs index 609f9f3c46..1c863c416c 100644 --- a/modules/setting-management/app/Volo.Abp.SettingManagement.DemoApp/DemoAppModule.cs +++ b/modules/setting-management/app/Volo.Abp.SettingManagement.DemoApp/DemoAppModule.cs @@ -86,6 +86,8 @@ namespace Volo.Abp.SettingManagement.DemoApp options.Languages.Add(new LanguageInfo("tr", "tr", "Türkçe")); options.Languages.Add(new LanguageInfo("fi", "fi", "Finnish")); options.Languages.Add(new LanguageInfo("fr", "fr", "Français")); + options.Languages.Add(new LanguageInfo("hi", "hi", "Hindi", "in")); + options.Languages.Add(new LanguageInfo("it", "it", "Italian", "it")); }); Configure(options => diff --git a/modules/setting-management/app/Volo.Abp.SettingManagement.DemoApp/Volo.Abp.SettingManagement.DemoApp.abppkg.json b/modules/setting-management/app/Volo.Abp.SettingManagement.DemoApp/Volo.Abp.SettingManagement.DemoApp.abppkg.json new file mode 100644 index 0000000000..9e26dfeeb6 --- /dev/null +++ b/modules/setting-management/app/Volo.Abp.SettingManagement.DemoApp/Volo.Abp.SettingManagement.DemoApp.abppkg.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/modules/setting-management/src/Volo.Abp.SettingManagement.Application.Contracts/Volo.Abp.SettingManagement.Application.Contracts.abppkg.json b/modules/setting-management/src/Volo.Abp.SettingManagement.Application.Contracts/Volo.Abp.SettingManagement.Application.Contracts.abppkg.json new file mode 100644 index 0000000000..49032794e2 --- /dev/null +++ b/modules/setting-management/src/Volo.Abp.SettingManagement.Application.Contracts/Volo.Abp.SettingManagement.Application.Contracts.abppkg.json @@ -0,0 +1,3 @@ +{ + "role": "lib.application-contracts" +} \ No newline at end of file diff --git a/modules/setting-management/src/Volo.Abp.SettingManagement.Application/Volo.Abp.SettingManagement.Application.abppkg.json b/modules/setting-management/src/Volo.Abp.SettingManagement.Application/Volo.Abp.SettingManagement.Application.abppkg.json new file mode 100644 index 0000000000..412567ac33 --- /dev/null +++ b/modules/setting-management/src/Volo.Abp.SettingManagement.Application/Volo.Abp.SettingManagement.Application.abppkg.json @@ -0,0 +1,3 @@ +{ + "role": "lib.application" +} \ No newline at end of file diff --git a/modules/setting-management/src/Volo.Abp.SettingManagement.Blazor.Server/Volo.Abp.SettingManagement.Blazor.Server.abppkg.json b/modules/setting-management/src/Volo.Abp.SettingManagement.Blazor.Server/Volo.Abp.SettingManagement.Blazor.Server.abppkg.json new file mode 100644 index 0000000000..ef40d81585 --- /dev/null +++ b/modules/setting-management/src/Volo.Abp.SettingManagement.Blazor.Server/Volo.Abp.SettingManagement.Blazor.Server.abppkg.json @@ -0,0 +1,3 @@ +{ + "role": "lib.blazor-server" +} \ No newline at end of file diff --git a/modules/setting-management/src/Volo.Abp.SettingManagement.Blazor.WebAssembly/Volo.Abp.SettingManagement.Blazor.WebAssembly.abppkg.json b/modules/setting-management/src/Volo.Abp.SettingManagement.Blazor.WebAssembly/Volo.Abp.SettingManagement.Blazor.WebAssembly.abppkg.json new file mode 100644 index 0000000000..471ef5e067 --- /dev/null +++ b/modules/setting-management/src/Volo.Abp.SettingManagement.Blazor.WebAssembly/Volo.Abp.SettingManagement.Blazor.WebAssembly.abppkg.json @@ -0,0 +1,3 @@ +{ + "role": "lib.blazor-wasm" +} \ No newline at end of file diff --git a/modules/setting-management/src/Volo.Abp.SettingManagement.Blazor/Volo.Abp.SettingManagement.Blazor.abppkg.json b/modules/setting-management/src/Volo.Abp.SettingManagement.Blazor/Volo.Abp.SettingManagement.Blazor.abppkg.json new file mode 100644 index 0000000000..19c29b7b8b --- /dev/null +++ b/modules/setting-management/src/Volo.Abp.SettingManagement.Blazor/Volo.Abp.SettingManagement.Blazor.abppkg.json @@ -0,0 +1,3 @@ +{ + "role": "lib.blazor" +} \ No newline at end of file diff --git a/modules/setting-management/src/Volo.Abp.SettingManagement.Domain.Shared/Volo.Abp.SettingManagement.Domain.Shared.abppkg.json b/modules/setting-management/src/Volo.Abp.SettingManagement.Domain.Shared/Volo.Abp.SettingManagement.Domain.Shared.abppkg.json new file mode 100644 index 0000000000..8b3de05f76 --- /dev/null +++ b/modules/setting-management/src/Volo.Abp.SettingManagement.Domain.Shared/Volo.Abp.SettingManagement.Domain.Shared.abppkg.json @@ -0,0 +1,3 @@ +{ + "role": "lib.domain-shared" +} \ No newline at end of file diff --git a/modules/setting-management/src/Volo.Abp.SettingManagement.Domain.Shared/Volo/Abp/SettingManagement/Localization/Resources/AbpSettingManagement/hi.json b/modules/setting-management/src/Volo.Abp.SettingManagement.Domain.Shared/Volo/Abp/SettingManagement/Localization/Resources/AbpSettingManagement/hi.json new file mode 100644 index 0000000000..674fba6790 --- /dev/null +++ b/modules/setting-management/src/Volo.Abp.SettingManagement.Domain.Shared/Volo/Abp/SettingManagement/Localization/Resources/AbpSettingManagement/hi.json @@ -0,0 +1,19 @@ +{ + "culture": "hi", + "texts": { + "Settings": "समायोजन", + "SuccessfullySaved": "सफलतापूर्वक संचित कर लिया गया है", + "Permission:SettingManagement": "प्रबंधन की स्थापना", + "Permission:Emailing": "ईमेल से भेजना", + "Menu:Emailing": "ईमेल से भेजना", + "SmtpHost": "मेज़बान", + "SmtpPort": "बंदरगाह", + "SmtpUserName": "उपयोगकर्ता नाम", + "SmtpPassword": "कुंजिका", + "SmtpDomain": "डोमेन", + "SmtpEnableSsl": "Ssl सक्षम करें", + "SmtpUseDefaultCredentials": "डिफ़ॉल्ट क्रेडेंशियल्स का उपयोग करें", + "DefaultFromAddress": "पते से डिफ़ॉल्ट", + "DefaultFromDisplayName": "प्रदर्शन नाम से डिफ़ॉल्ट" + } +} \ No newline at end of file diff --git a/modules/setting-management/src/Volo.Abp.SettingManagement.Domain.Shared/Volo/Abp/SettingManagement/Localization/Resources/AbpSettingManagement/it.json b/modules/setting-management/src/Volo.Abp.SettingManagement.Domain.Shared/Volo/Abp/SettingManagement/Localization/Resources/AbpSettingManagement/it.json new file mode 100644 index 0000000000..5fde62505d --- /dev/null +++ b/modules/setting-management/src/Volo.Abp.SettingManagement.Domain.Shared/Volo/Abp/SettingManagement/Localization/Resources/AbpSettingManagement/it.json @@ -0,0 +1,19 @@ +{ + "culture": "it", + "texts": { + "Settings": "impostazioni", + "SuccessfullySaved": "Salvato con successo", + "Permission:SettingManagement": "Gestione delle impostazioni", + "Permission:Emailing": "Invio di e-mail", + "Menu:Emailing": "Invio di e-mail", + "SmtpHost": "Ospite", + "SmtpPort": "Porta", + "SmtpUserName": "Nome utente", + "SmtpPassword": "Parola d'ordine", + "SmtpDomain": "Dominio", + "SmtpEnableSsl": "Abilita SSL", + "SmtpUseDefaultCredentials": "Usa credenziali predefinite", + "DefaultFromAddress": "Indirizzo predefinito dall'indirizzo", + "DefaultFromDisplayName": "Predefinito dal nome visualizzato" + } +} \ No newline at end of file diff --git a/modules/setting-management/src/Volo.Abp.SettingManagement.Domain/Volo.Abp.SettingManagement.Domain.abppkg.json b/modules/setting-management/src/Volo.Abp.SettingManagement.Domain/Volo.Abp.SettingManagement.Domain.abppkg.json new file mode 100644 index 0000000000..1d574efe45 --- /dev/null +++ b/modules/setting-management/src/Volo.Abp.SettingManagement.Domain/Volo.Abp.SettingManagement.Domain.abppkg.json @@ -0,0 +1,3 @@ +{ + "role": "lib.domain" +} \ No newline at end of file diff --git a/modules/setting-management/src/Volo.Abp.SettingManagement.EntityFrameworkCore/Volo.Abp.SettingManagement.EntityFrameworkCore.abppkg.json b/modules/setting-management/src/Volo.Abp.SettingManagement.EntityFrameworkCore/Volo.Abp.SettingManagement.EntityFrameworkCore.abppkg.json new file mode 100644 index 0000000000..e1c64f0175 --- /dev/null +++ b/modules/setting-management/src/Volo.Abp.SettingManagement.EntityFrameworkCore/Volo.Abp.SettingManagement.EntityFrameworkCore.abppkg.json @@ -0,0 +1,3 @@ +{ + "role": "lib.ef" +} \ No newline at end of file diff --git a/modules/setting-management/src/Volo.Abp.SettingManagement.HttpApi.Client/Volo.Abp.SettingManagement.HttpApi.Client.abppkg.json b/modules/setting-management/src/Volo.Abp.SettingManagement.HttpApi.Client/Volo.Abp.SettingManagement.HttpApi.Client.abppkg.json new file mode 100644 index 0000000000..7deef5e383 --- /dev/null +++ b/modules/setting-management/src/Volo.Abp.SettingManagement.HttpApi.Client/Volo.Abp.SettingManagement.HttpApi.Client.abppkg.json @@ -0,0 +1,3 @@ +{ + "role": "lib.http-api-client" +} \ No newline at end of file diff --git a/modules/setting-management/src/Volo.Abp.SettingManagement.HttpApi/Volo.Abp.SettingManagement.HttpApi.abppkg.json b/modules/setting-management/src/Volo.Abp.SettingManagement.HttpApi/Volo.Abp.SettingManagement.HttpApi.abppkg.json new file mode 100644 index 0000000000..515bfe64c4 --- /dev/null +++ b/modules/setting-management/src/Volo.Abp.SettingManagement.HttpApi/Volo.Abp.SettingManagement.HttpApi.abppkg.json @@ -0,0 +1,3 @@ +{ + "role": "lib.http-api" +} \ No newline at end of file diff --git a/modules/setting-management/src/Volo.Abp.SettingManagement.MongoDB/Volo.Abp.SettingManagement.MongoDB.abppkg.json b/modules/setting-management/src/Volo.Abp.SettingManagement.MongoDB/Volo.Abp.SettingManagement.MongoDB.abppkg.json new file mode 100644 index 0000000000..8b23fd1e69 --- /dev/null +++ b/modules/setting-management/src/Volo.Abp.SettingManagement.MongoDB/Volo.Abp.SettingManagement.MongoDB.abppkg.json @@ -0,0 +1,3 @@ +{ + "role": "lib.mongodb" +} \ No newline at end of file diff --git a/modules/setting-management/src/Volo.Abp.SettingManagement.Web/Volo.Abp.SettingManagement.Web.abppkg.json b/modules/setting-management/src/Volo.Abp.SettingManagement.Web/Volo.Abp.SettingManagement.Web.abppkg.json new file mode 100644 index 0000000000..930c4018b3 --- /dev/null +++ b/modules/setting-management/src/Volo.Abp.SettingManagement.Web/Volo.Abp.SettingManagement.Web.abppkg.json @@ -0,0 +1,3 @@ +{ + "role": "lib.mvc" +} \ No newline at end of file diff --git a/modules/setting-management/test/Volo.Abp.SettingManagement.EntityFrameworkCore.Tests/Volo.Abp.SettingManagement.EntityFrameworkCore.Tests.abppkg.json b/modules/setting-management/test/Volo.Abp.SettingManagement.EntityFrameworkCore.Tests/Volo.Abp.SettingManagement.EntityFrameworkCore.Tests.abppkg.json new file mode 100644 index 0000000000..a686451fbc --- /dev/null +++ b/modules/setting-management/test/Volo.Abp.SettingManagement.EntityFrameworkCore.Tests/Volo.Abp.SettingManagement.EntityFrameworkCore.Tests.abppkg.json @@ -0,0 +1,3 @@ +{ + "role": "lib.test" +} \ No newline at end of file diff --git a/modules/setting-management/test/Volo.Abp.SettingManagement.MongoDB.Tests/Volo.Abp.SettingManagement.MongoDB.Tests.abppkg.json b/modules/setting-management/test/Volo.Abp.SettingManagement.MongoDB.Tests/Volo.Abp.SettingManagement.MongoDB.Tests.abppkg.json new file mode 100644 index 0000000000..a686451fbc --- /dev/null +++ b/modules/setting-management/test/Volo.Abp.SettingManagement.MongoDB.Tests/Volo.Abp.SettingManagement.MongoDB.Tests.abppkg.json @@ -0,0 +1,3 @@ +{ + "role": "lib.test" +} \ No newline at end of file diff --git a/modules/setting-management/test/Volo.Abp.SettingManagement.TestBase/Volo.Abp.SettingManagement.TestBase.abppkg.json b/modules/setting-management/test/Volo.Abp.SettingManagement.TestBase/Volo.Abp.SettingManagement.TestBase.abppkg.json new file mode 100644 index 0000000000..9e26dfeeb6 --- /dev/null +++ b/modules/setting-management/test/Volo.Abp.SettingManagement.TestBase/Volo.Abp.SettingManagement.TestBase.abppkg.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/modules/setting-management/test/Volo.Abp.SettingManagement.Tests/Volo.Abp.SettingManagement.Tests.abppkg.json b/modules/setting-management/test/Volo.Abp.SettingManagement.Tests/Volo.Abp.SettingManagement.Tests.abppkg.json new file mode 100644 index 0000000000..a686451fbc --- /dev/null +++ b/modules/setting-management/test/Volo.Abp.SettingManagement.Tests/Volo.Abp.SettingManagement.Tests.abppkg.json @@ -0,0 +1,3 @@ +{ + "role": "lib.test" +} \ No newline at end of file diff --git a/modules/tenant-management/src/Volo.Abp.TenantManagement.Blazor/Navigation/TenantManagementBlazorMenuContributor.cs b/modules/tenant-management/src/Volo.Abp.TenantManagement.Blazor/Navigation/TenantManagementBlazorMenuContributor.cs index 3f4fa8683c..193cfb034b 100644 --- a/modules/tenant-management/src/Volo.Abp.TenantManagement.Blazor/Navigation/TenantManagementBlazorMenuContributor.cs +++ b/modules/tenant-management/src/Volo.Abp.TenantManagement.Blazor/Navigation/TenantManagementBlazorMenuContributor.cs @@ -1,6 +1,7 @@ using System.Threading.Tasks; using Volo.Abp.TenantManagement.Localization; using Volo.Abp.UI.Navigation; +using Volo.Abp.Authorization.Permissions; namespace Volo.Abp.TenantManagement.Blazor.Navigation { @@ -27,9 +28,8 @@ namespace Volo.Abp.TenantManagement.Blazor.Navigation tenantManagementMenuItem.AddItem(new ApplicationMenuItem( TenantManagementMenuNames.Tenants, l["Tenants"], - url: "~/tenant-management/tenants", - requiredPermissionName: TenantManagementPermissions.Tenants.Default - )); + url: "~/tenant-management/tenants" + ).RequirePermissions(TenantManagementPermissions.Tenants.Default)); return Task.CompletedTask; } diff --git a/modules/tenant-management/src/Volo.Abp.TenantManagement.Domain.Shared/Volo/Abp/TenantManagement/Localization/Resources/hi.json b/modules/tenant-management/src/Volo.Abp.TenantManagement.Domain.Shared/Volo/Abp/TenantManagement/Localization/Resources/hi.json new file mode 100644 index 0000000000..1094744a16 --- /dev/null +++ b/modules/tenant-management/src/Volo.Abp.TenantManagement.Domain.Shared/Volo/Abp/TenantManagement/Localization/Resources/hi.json @@ -0,0 +1,23 @@ +{ + "culture": "hi", + "texts": { + "Menu:TenantManagement": "किरायेदार प्रबंधन", + "Tenants": "किरायेदारों", + "NewTenant": "नया किरायेदार", + "TenantName": "किरायेदार का नाम", + "DisplayName:TenantName": "किरायेदार का नाम", + "TenantDeletionConfirmationMessage": "किरायेदार '{0}' हटा दिया जाएगा। क्या आप इसकी पुष्टि करते हैं?", + "ConnectionStrings": "कनेक्शन स्ट्रिंग्स", + "DisplayName:DefaultConnectionString": "डिफ़ॉल्ट कनेक्शन स्ट्रिंग", + "DisplayName:UseSharedDatabase": "साझा डेटाबेस का उपयोग करें", + "ManageHostFeatures": "होस्ट सुविधाएँ प्रबंधित करें", + "Permission:TenantManagement": "किरायेदार प्रबंधन", + "Permission:Create": "सृजन करना", + "Permission:Edit": "संपादित करें", + "Permission:Delete": "हटाएं", + "Permission:ManageConnectionStrings": "कनेक्शन स्ट्रिंग्स प्रबंधित करें", + "Permission:ManageFeatures": "सुविधाओं को प्रबंधित करें", + "DisplayName:AdminEmailAddress": "ईमेल पता", + "DisplayName:AdminPassword": "व्यवस्थापक का पारण शब्द" + } +} \ No newline at end of file diff --git a/modules/tenant-management/src/Volo.Abp.TenantManagement.Domain.Shared/Volo/Abp/TenantManagement/Localization/Resources/it.json b/modules/tenant-management/src/Volo.Abp.TenantManagement.Domain.Shared/Volo/Abp/TenantManagement/Localization/Resources/it.json new file mode 100644 index 0000000000..e635da5d1f --- /dev/null +++ b/modules/tenant-management/src/Volo.Abp.TenantManagement.Domain.Shared/Volo/Abp/TenantManagement/Localization/Resources/it.json @@ -0,0 +1,23 @@ +{ + "culture": "it", + "texts": { + "Menu:TenantManagement": "Gestione inquilini", + "Tenants": "Inquilini", + "NewTenant": "Nuovo inquilino", + "TenantName": "Nome inquilino", + "DisplayName:TenantName": "Nome inquilino", + "TenantDeletionConfirmationMessage": "Il tenant \"{0}\" verrà eliminato. Lo confermi?", + "ConnectionStrings": "Stringhe di connessione", + "DisplayName:DefaultConnectionString": "Stringa di connessione predefinita", + "DisplayName:UseSharedDatabase": "Usa il database condiviso", + "ManageHostFeatures": "Gestisci le funzionalità dell'host", + "Permission:TenantManagement": "Gestione inquilini", + "Permission:Create": "Creare", + "Permission:Edit": "modificare", + "Permission:Delete": "Elimina", + "Permission:ManageConnectionStrings": "Gestisci le stringhe di connessione", + "Permission:ManageFeatures": "Gestisci le funzionalità", + "DisplayName:AdminEmailAddress": "Indirizzo e-mail dell'amministratore", + "DisplayName:AdminPassword": "Password dell'amministratore" + } +} \ No newline at end of file diff --git a/modules/tenant-management/src/Volo.Abp.TenantManagement.Domain/Volo/Abp/TenantManagement/AbpTenantManagementDomainMappingProfile.cs b/modules/tenant-management/src/Volo.Abp.TenantManagement.Domain/Volo/Abp/TenantManagement/AbpTenantManagementDomainMappingProfile.cs index 31eb7c6d19..539cafb4bb 100644 --- a/modules/tenant-management/src/Volo.Abp.TenantManagement.Domain/Volo/Abp/TenantManagement/AbpTenantManagementDomainMappingProfile.cs +++ b/modules/tenant-management/src/Volo.Abp.TenantManagement.Domain/Volo/Abp/TenantManagement/AbpTenantManagementDomainMappingProfile.cs @@ -22,7 +22,8 @@ namespace Volo.Abp.TenantManagement return connStrings; }); - }); + }) + .ForMember(x => x.IsActive, x => x.Ignore()); CreateMap(); } diff --git a/modules/tenant-management/src/Volo.Abp.TenantManagement.Web/Navigation/AbpTenantManagementWebMainMenuContributor.cs b/modules/tenant-management/src/Volo.Abp.TenantManagement.Web/Navigation/AbpTenantManagementWebMainMenuContributor.cs index c3ebaa39b5..1cc917c311 100644 --- a/modules/tenant-management/src/Volo.Abp.TenantManagement.Web/Navigation/AbpTenantManagementWebMainMenuContributor.cs +++ b/modules/tenant-management/src/Volo.Abp.TenantManagement.Web/Navigation/AbpTenantManagementWebMainMenuContributor.cs @@ -4,6 +4,7 @@ using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Localization; using Volo.Abp.TenantManagement.Localization; using Volo.Abp.UI.Navigation; +using Volo.Abp.Authorization.Permissions; namespace Volo.Abp.TenantManagement.Web.Navigation { @@ -23,7 +24,7 @@ namespace Volo.Abp.TenantManagement.Web.Navigation var tenantManagementMenuItem = new ApplicationMenuItem(TenantManagementMenuNames.GroupName, l["Menu:TenantManagement"], icon: "fa fa-users"); administrationMenu.AddItem(tenantManagementMenuItem); - tenantManagementMenuItem.AddItem(new ApplicationMenuItem(TenantManagementMenuNames.Tenants, l["Tenants"], url: "~/TenantManagement/Tenants", requiredPermissionName: TenantManagementPermissions.Tenants.Default)); + tenantManagementMenuItem.AddItem(new ApplicationMenuItem(TenantManagementMenuNames.Tenants, l["Tenants"], url: "~/TenantManagement/Tenants").RequirePermissions(TenantManagementPermissions.Tenants.Default)); return Task.CompletedTask; } diff --git a/modules/users/Volo.Abp.Users.abpmdl.json b/modules/users/Volo.Abp.Users.abpmdl.json index 63ec84a14e..f2b03eef4f 100644 --- a/modules/users/Volo.Abp.Users.abpmdl.json +++ b/modules/users/Volo.Abp.Users.abpmdl.json @@ -5,14 +5,6 @@ } }, "packages": { - "Volo.Abp.Users.Abstractions": { - "path": "src/Volo.Abp.Users.Abstractions/Volo.Abp.Users.Abstractions.abppkg.json", - "folder": "src" - }, - "Volo.Abp.Users.Domain.Shared": { - "path": "src/Volo.Abp.Users.Domain.Shared/Volo.Abp.Users.Domain.Shared.abppkg.json", - "folder": "src" - }, "Volo.Abp.Users.Domain": { "path": "src/Volo.Abp.Users.Domain/Volo.Abp.Users.Domain.abppkg.json", "folder": "src" @@ -21,6 +13,14 @@ "path": "src/Volo.Abp.Users.EntityFrameworkCore/Volo.Abp.Users.EntityFrameworkCore.abppkg.json", "folder": "src" }, + "Volo.Abp.Users.Domain.Shared": { + "path": "src/Volo.Abp.Users.Domain.Shared/Volo.Abp.Users.Domain.Shared.abppkg.json", + "folder": "src" + }, + "Volo.Abp.Users.Abstractions": { + "path": "src/Volo.Abp.Users.Abstractions/Volo.Abp.Users.Abstractions.abppkg.json", + "folder": "src" + }, "Volo.Abp.Users.MongoDB": { "path": "src/Volo.Abp.Users.MongoDB/Volo.Abp.Users.MongoDB.abppkg.json", "folder": "src" diff --git a/modules/users/src/Volo.Abp.Users.Domain.Shared/Volo.Abp.Users.Domain.Shared.abppkg.json b/modules/users/src/Volo.Abp.Users.Domain.Shared/Volo.Abp.Users.Domain.Shared.abppkg.json index 169c71c1e1..8b3de05f76 100644 --- a/modules/users/src/Volo.Abp.Users.Domain.Shared/Volo.Abp.Users.Domain.Shared.abppkg.json +++ b/modules/users/src/Volo.Abp.Users.Domain.Shared/Volo.Abp.Users.Domain.Shared.abppkg.json @@ -1,3 +1,3 @@ { - "role": "lib.domain.shared" + "role": "lib.domain-shared" } \ No newline at end of file diff --git a/modules/users/src/Volo.Abp.Users.EntityFrameworkCore/Volo/Abp/Users/EntityFrameworkCore/EfCoreAbpUserRepositoryBase.cs b/modules/users/src/Volo.Abp.Users.EntityFrameworkCore/Volo/Abp/Users/EntityFrameworkCore/EfCoreAbpUserRepositoryBase.cs index 529af15778..635d9fc8fd 100644 --- a/modules/users/src/Volo.Abp.Users.EntityFrameworkCore/Volo/Abp/Users/EntityFrameworkCore/EfCoreAbpUserRepositoryBase.cs +++ b/modules/users/src/Volo.Abp.Users.EntityFrameworkCore/Volo/Abp/Users/EntityFrameworkCore/EfCoreAbpUserRepositoryBase.cs @@ -44,9 +44,9 @@ namespace Volo.Abp.Users.EntityFrameworkCore !filter.IsNullOrWhiteSpace(), u => u.UserName.Contains(filter) || - u.Email.Contains(filter) || - u.Name.Contains(filter) || - u.Surname.Contains(filter) + (u.Email != null && u.Email.Contains(filter)) || + (u.Name != null && u.Name.Contains(filter)) || + (u.Surname != null && u.Surname.Contains(filter)) ) .OrderBy(sorting.IsNullOrEmpty() ? nameof(IUser.UserName) : sorting) .PageBy(skipCount, maxResultCount) @@ -62,9 +62,9 @@ namespace Volo.Abp.Users.EntityFrameworkCore !filter.IsNullOrWhiteSpace(), u => u.UserName.Contains(filter) || - u.Email.Contains(filter) || - u.Name.Contains(filter) || - u.Surname.Contains(filter) + (u.Email != null && u.Email.Contains(filter)) || + (u.Name != null && u.Name.Contains(filter)) || + (u.Surname != null && u.Surname.Contains(filter)) ) .LongCountAsync(GetCancellationToken(cancellationToken)); } diff --git a/modules/users/src/Volo.Abp.Users.MongoDB/Volo/Abp/Users/MongoDB/MongoUserRepositoryBase.cs b/modules/users/src/Volo.Abp.Users.MongoDB/Volo/Abp/Users/MongoDB/MongoUserRepositoryBase.cs index a24cb3b788..14fa2ea6d0 100644 --- a/modules/users/src/Volo.Abp.Users.MongoDB/Volo/Abp/Users/MongoDB/MongoUserRepositoryBase.cs +++ b/modules/users/src/Volo.Abp.Users.MongoDB/Volo/Abp/Users/MongoDB/MongoUserRepositoryBase.cs @@ -50,9 +50,9 @@ namespace Volo.Abp.Users.MongoDB !filter.IsNullOrWhiteSpace(), u => u.UserName.Contains(filter) || - u.Email.Contains(filter) || - u.Name.Contains(filter) || - u.Surname.Contains(filter) + (u.Email != null && u.Email.Contains(filter)) || + (u.Name != null && u.Name.Contains(filter)) || + (u.Surname != null && u.Surname.Contains(filter)) ) .OrderBy(sorting.IsNullOrEmpty() ? nameof(IUserData.UserName) : sorting) .As>() @@ -68,9 +68,9 @@ namespace Volo.Abp.Users.MongoDB !filter.IsNullOrWhiteSpace(), u => u.UserName.Contains(filter) || - u.Email.Contains(filter) || - u.Name.Contains(filter) || - u.Surname.Contains(filter) + (u.Email != null && u.Email.Contains(filter)) || + (u.Name != null && u.Name.Contains(filter)) || + (u.Surname != null && u.Surname.Contains(filter)) ) .LongCountAsync(cancellationToken); } diff --git a/modules/virtual-file-explorer/app/Volo.Abp.VirtualFileExplorer.DemoApp/AbpVirtualFileExplorerDemoAppModule.cs b/modules/virtual-file-explorer/app/Volo.Abp.VirtualFileExplorer.DemoApp/AbpVirtualFileExplorerDemoAppModule.cs index abcf7db794..4473473a87 100644 --- a/modules/virtual-file-explorer/app/Volo.Abp.VirtualFileExplorer.DemoApp/AbpVirtualFileExplorerDemoAppModule.cs +++ b/modules/virtual-file-explorer/app/Volo.Abp.VirtualFileExplorer.DemoApp/AbpVirtualFileExplorerDemoAppModule.cs @@ -22,6 +22,8 @@ namespace Volo.Abp.VirtualFileExplorer.DemoApp options.Languages.Add(new LanguageInfo("en", "en", "English")); options.Languages.Add(new LanguageInfo("fi", "fi", "Finnish")); options.Languages.Add(new LanguageInfo("fr", "fr", "Français")); + options.Languages.Add(new LanguageInfo("hi", "hi", "Hindi", "in")); + options.Languages.Add(new LanguageInfo("it", "it", "Italian", "it")); options.Languages.Add(new LanguageInfo("hu", "hu", "Magyar")); options.Languages.Add(new LanguageInfo("tr", "tr", "Türkçe")); options.Languages.Add(new LanguageInfo("zh-Hans", "zh-Hans", "简体中文")); diff --git a/modules/virtual-file-explorer/src/Volo.Abp.VirtualFileExplorer.Web/Localization/Resources/hi.json b/modules/virtual-file-explorer/src/Volo.Abp.VirtualFileExplorer.Web/Localization/Resources/hi.json new file mode 100644 index 0000000000..09056ed265 --- /dev/null +++ b/modules/virtual-file-explorer/src/Volo.Abp.VirtualFileExplorer.Web/Localization/Resources/hi.json @@ -0,0 +1,14 @@ +{ + "culture": "hi", + "texts": { + "VirtualFileExplorer": "आभासी फ़ाइल एक्सप्लोरर", + "VirtualFileType": "वर्चुअल फ़ाइल प्रकार", + "Menu:VirtualFileExplorer": "आभासी फ़ाइल एक्सप्लोरर", + "LastUpdateTime": "अंतिम अद्यतन समय", + "VirtualFileName": "वर्चुअल फ़ाइल नाम", + "FileContent": "फ़ाइल सामग्री", + "Size": "आकार", + "BackToRoot": "वापस रूट करने के लिए", + "EmptyFileInfoList": "कोई वर्चुअल फ़ाइल नहीं हैं" + } +} \ No newline at end of file diff --git a/modules/virtual-file-explorer/src/Volo.Abp.VirtualFileExplorer.Web/Localization/Resources/it.json b/modules/virtual-file-explorer/src/Volo.Abp.VirtualFileExplorer.Web/Localization/Resources/it.json new file mode 100644 index 0000000000..2615bab475 --- /dev/null +++ b/modules/virtual-file-explorer/src/Volo.Abp.VirtualFileExplorer.Web/Localization/Resources/it.json @@ -0,0 +1,14 @@ +{ + "culture": "it", + "texts": { + "VirtualFileExplorer": "Esplora file virtuale", + "VirtualFileType": "Tipo di file virtuale", + "Menu:VirtualFileExplorer": "Esplora file virtuale", + "LastUpdateTime": "Ora dell'ultimo aggiornamento", + "VirtualFileName": "Nome del file virtuale", + "FileContent": "Contenuto del file", + "Size": "Dimensione", + "BackToRoot": "Torna alla radice", + "EmptyFileInfoList": "Non ci sono file virtuali" + } +} \ No newline at end of file diff --git a/npm/ng-packs/packages/core/src/lib/tests/localization.service.spec.ts b/npm/ng-packs/packages/core/src/lib/tests/localization.service.spec.ts index 4e4313caf5..b130afcc23 100644 --- a/npm/ng-packs/packages/core/src/lib/tests/localization.service.spec.ts +++ b/npm/ng-packs/packages/core/src/lib/tests/localization.service.spec.ts @@ -12,7 +12,6 @@ describe('LocalizationService', () => { let spectator: SpectatorService; let sessionState: SpyObject; let configState: SpyObject; - let router: SpyObject; let service: LocalizationService; const createService = createServiceFactory({ diff --git a/npm/ng-packs/packages/theme-shared/extensions/src/tests/enum.util.spec.ts b/npm/ng-packs/packages/theme-shared/extensions/src/tests/enum.util.spec.ts index c757fad1e5..6c9ffeaa38 100644 --- a/npm/ng-packs/packages/theme-shared/extensions/src/tests/enum.util.spec.ts +++ b/npm/ng-packs/packages/theme-shared/extensions/src/tests/enum.util.spec.ts @@ -110,5 +110,5 @@ function createMockLocalizationService() { const configState = new ConfigStateService(); configState.setState({ localization: mockL10n } as any); - return new LocalizationService(mockSessionState, null, null, null, configState, null); + return new LocalizationService(mockSessionState, null, null, configState, null); } diff --git a/npm/ng-packs/packages/theme-shared/src/lib/handlers/datepicker-config.ts b/npm/ng-packs/packages/theme-shared/src/lib/handlers/datepicker-config.ts new file mode 100644 index 0000000000..6fc30c8577 --- /dev/null +++ b/npm/ng-packs/packages/theme-shared/src/lib/handlers/datepicker-config.ts @@ -0,0 +1,11 @@ +import { Injector } from '@angular/core'; +import { NgbInputDatepickerConfig } from '@ng-bootstrap/ng-bootstrap'; + +export function initDatepickerConfig(injector: Injector) { + const datepickerConfig = injector.get(NgbInputDatepickerConfig, null); + if (datepickerConfig) { + datepickerConfig.container = 'body'; + } + + return () => {}; +} diff --git a/npm/ng-packs/packages/theme-shared/src/lib/handlers/index.ts b/npm/ng-packs/packages/theme-shared/src/lib/handlers/index.ts index 11eb07398e..a9253984b5 100644 --- a/npm/ng-packs/packages/theme-shared/src/lib/handlers/index.ts +++ b/npm/ng-packs/packages/theme-shared/src/lib/handlers/index.ts @@ -1,2 +1,3 @@ export * from './error.handler'; export * from './lazy-style.handler'; +export * from './datepicker-config'; diff --git a/npm/ng-packs/packages/theme-shared/src/lib/theme-shared.module.ts b/npm/ng-packs/packages/theme-shared/src/lib/theme-shared.module.ts index ddf1d6a5a3..72b99aa7e4 100644 --- a/npm/ng-packs/packages/theme-shared/src/lib/theme-shared.module.ts +++ b/npm/ng-packs/packages/theme-shared/src/lib/theme-shared.module.ts @@ -38,6 +38,7 @@ import { THEME_SHARED_APPEND_CONTENT } from './tokens/append-content.token'; import { HTTP_ERROR_CONFIG, httpErrorConfigFactory } from './tokens/http-error.token'; import { DateParserFormatter } from './utils/date-parser-formatter'; import { ModalCloseDirective } from './components/modal/modal-close.directive'; +import { initDatepickerConfig } from './handlers/datepicker-config'; const declarationsWithExports = [ BreadcrumbComponent, @@ -110,6 +111,12 @@ export class ThemeSharedModule { deps: [Injector], useFactory: initLazyStyleHandler, }, + { + provide: APP_INITIALIZER, + multi: true, + deps: [Injector], + useFactory: initDatepickerConfig, + }, { provide: HTTP_ERROR_CONFIG, useValue: httpErrorConfig }, { provide: 'HTTP_ERROR_CONFIG', diff --git a/npm/ng-packs/packages/theme-shared/src/public-api.ts b/npm/ng-packs/packages/theme-shared/src/public-api.ts index 5a4f9efe95..845655402d 100644 --- a/npm/ng-packs/packages/theme-shared/src/public-api.ts +++ b/npm/ng-packs/packages/theme-shared/src/public-api.ts @@ -8,7 +8,7 @@ export { BOOTSTRAP } from './lib/constants/styles'; export * from './lib/constants/validation'; export * from './lib/directives'; export * from './lib/enums'; -export { ErrorHandler } from './lib/handlers'; +export * from './lib/handlers'; export * from './lib/models'; export * from './lib/providers'; export * from './lib/services'; diff --git a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Blazor.Server.Tiered/Menus/MyProjectNameMenuContributor.cs b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Blazor.Server.Tiered/Menus/MyProjectNameMenuContributor.cs index 52a15ed4b2..26ad3a6a4d 100644 --- a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Blazor.Server.Tiered/Menus/MyProjectNameMenuContributor.cs +++ b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Blazor.Server.Tiered/Menus/MyProjectNameMenuContributor.cs @@ -6,6 +6,7 @@ using MyCompanyName.MyProjectName.Localization; using MyCompanyName.MyProjectName.MultiTenancy; using Volo.Abp.Account.Localization; using Volo.Abp.Identity.Blazor; +using Volo.Abp.Authorization.Permissions; using Volo.Abp.SettingManagement.Blazor.Menus; using Volo.Abp.TenantManagement.Blazor.Navigation; using Volo.Abp.UI.Navigation; @@ -69,16 +70,11 @@ namespace MyCompanyName.MyProjectName.Blazor.Server.Tiered.Menus { var l = context.GetLocalizer(); var accountStringLocalizer = context.GetLocalizer(); - var currentUser = context.ServiceProvider.GetRequiredService(); - var identityServerUrl = _configuration["AuthServer:Authority"] ?? ""; - if (currentUser.IsAuthenticated) - { - context.Menu.AddItem(new ApplicationMenuItem("Account.Manage", accountStringLocalizer["ManageYourProfile"], - $"{identityServerUrl.EnsureEndsWith('/')}Account/Manage?returnUrl={_configuration["App:SelfUrl"]}", icon: "fa fa-cog", order: 1000, null, "_blank")); - context.Menu.AddItem(new ApplicationMenuItem("Account.Logout", l["Logout"], url: "~/Account/Logout", icon: "fa fa-power-off", order: int.MaxValue - 1000)); - } + context.Menu.AddItem(new ApplicationMenuItem("Account.Manage", accountStringLocalizer["ManageYourProfile"], + $"{identityServerUrl.EnsureEndsWith('/')}Account/Manage?returnUrl={_configuration["App:SelfUrl"]}", icon: "fa fa-cog", order: 1000, null, "_blank").RequireAuthenticated()); + context.Menu.AddItem(new ApplicationMenuItem("Account.Logout", l["Logout"], url: "~/Account/Logout", icon: "fa fa-power-off", order: int.MaxValue - 1000).RequireAuthenticated()); return Task.CompletedTask; } diff --git a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Blazor.Server.Tiered/MyProjectNameBlazorModule.cs b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Blazor.Server.Tiered/MyProjectNameBlazorModule.cs index 19c8621bc9..199a577745 100644 --- a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Blazor.Server.Tiered/MyProjectNameBlazorModule.cs +++ b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Blazor.Server.Tiered/MyProjectNameBlazorModule.cs @@ -218,6 +218,8 @@ namespace MyCompanyName.MyProjectName.Blazor.Server.Tiered options.Languages.Add(new LanguageInfo("hu", "hu", "Magyar")); options.Languages.Add(new LanguageInfo("fi", "fi", "Finnish")); options.Languages.Add(new LanguageInfo("fr", "fr", "Français")); + options.Languages.Add(new LanguageInfo("hi", "hi", "Hindi", "in")); + options.Languages.Add(new LanguageInfo("it", "it", "Italian", "it")); options.Languages.Add(new LanguageInfo("pt-BR", "pt-BR", "Português")); options.Languages.Add(new LanguageInfo("ru", "ru", "Русский")); options.Languages.Add(new LanguageInfo("tr", "tr", "Türkçe")); diff --git a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Blazor.Server/MyProjectNameBlazorModule.cs b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Blazor.Server/MyProjectNameBlazorModule.cs index 6d1bd7eb4d..1120f5ab0e 100644 --- a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Blazor.Server/MyProjectNameBlazorModule.cs +++ b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Blazor.Server/MyProjectNameBlazorModule.cs @@ -179,6 +179,8 @@ namespace MyCompanyName.MyProjectName.Blazor.Server options.Languages.Add(new LanguageInfo("hu", "hu", "Magyar")); options.Languages.Add(new LanguageInfo("fi", "fi", "Finnish")); options.Languages.Add(new LanguageInfo("fr", "fr", "Français")); + options.Languages.Add(new LanguageInfo("hi", "hi", "Hindi", "in")); + options.Languages.Add(new LanguageInfo("it", "it", "Italian", "it")); options.Languages.Add(new LanguageInfo("pt-BR", "pt-BR", "Português")); options.Languages.Add(new LanguageInfo("ru", "ru", "Русский")); options.Languages.Add(new LanguageInfo("tr", "tr", "Türkçe")); diff --git a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Blazor/Menus/MyProjectNameMenuContributor.cs b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Blazor/Menus/MyProjectNameMenuContributor.cs index c42223526a..f8a0f7e509 100644 --- a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Blazor/Menus/MyProjectNameMenuContributor.cs +++ b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Blazor/Menus/MyProjectNameMenuContributor.cs @@ -4,6 +4,7 @@ using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using MyCompanyName.MyProjectName.Localization; using Volo.Abp.Account.Localization; +using Volo.Abp.Authorization.Permissions; using Volo.Abp.UI.Navigation; using Volo.Abp.Users; @@ -50,20 +51,16 @@ namespace MyCompanyName.MyProjectName.Blazor.Menus private Task ConfigureUserMenuAsync(MenuConfigurationContext context) { var accountStringLocalizer = context.GetLocalizer(); - var currentUser = context.ServiceProvider.GetRequiredService(); var identityServerUrl = _configuration["AuthServer:Authority"] ?? ""; - if (currentUser.IsAuthenticated) - { - context.Menu.AddItem(new ApplicationMenuItem( - "Account.Manage", - accountStringLocalizer["ManageYourProfile"], - $"{identityServerUrl.EnsureEndsWith('/')}Account/Manage?returnUrl={_configuration["App:SelfUrl"]}", - icon: "fa fa-cog", - order: 1000, - null)); - } + context.Menu.AddItem(new ApplicationMenuItem( + "Account.Manage", + accountStringLocalizer["ManageYourProfile"], + $"{identityServerUrl.EnsureEndsWith('/')}Account/Manage?returnUrl={_configuration["App:SelfUrl"]}", + icon: "fa fa-cog", + order: 1000, + null).RequireAuthenticated()); return Task.CompletedTask; } diff --git a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Domain.Shared/Localization/MyProjectName/hi.json b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Domain.Shared/Localization/MyProjectName/hi.json new file mode 100644 index 0000000000..a1676bfd45 --- /dev/null +++ b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Domain.Shared/Localization/MyProjectName/hi.json @@ -0,0 +1,8 @@ +{ + "culture": "hi", + "texts": { + "Menu:Home": "घर", + "Welcome": "स्वागत हे", + "LongWelcomeMessage": "आवेदन करने के लिए आपका स्वागत है। यह एबीपी ढांचे पर आधारित एक स्टार्टअप परियोजना है। अधिक जानकारी के लिए, abp.io पर जाएं।" + } +} \ No newline at end of file diff --git a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Domain.Shared/Localization/MyProjectName/it.json b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Domain.Shared/Localization/MyProjectName/it.json new file mode 100644 index 0000000000..edd0ab7925 --- /dev/null +++ b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Domain.Shared/Localization/MyProjectName/it.json @@ -0,0 +1,8 @@ +{ + "culture": "it", + "texts": { + "Menu:Home": "Casa", + "Welcome": "benvenuto", + "LongWelcomeMessage": "Benvenuto nell'applicazione. Questo è un progetto di avvio basato sul framework ABP. Per ulteriori informazioni, visita abp.io." + } +} \ No newline at end of file diff --git a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.HttpApi.Host/MyProjectNameHttpApiHostModule.cs b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.HttpApi.Host/MyProjectNameHttpApiHostModule.cs index 54eb4043ce..fb7435d447 100644 --- a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.HttpApi.Host/MyProjectNameHttpApiHostModule.cs +++ b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.HttpApi.Host/MyProjectNameHttpApiHostModule.cs @@ -132,6 +132,8 @@ namespace MyCompanyName.MyProjectName options.Languages.Add(new LanguageInfo("en-GB", "en-GB", "English (UK)")); options.Languages.Add(new LanguageInfo("fi", "fi", "Finnish")); options.Languages.Add(new LanguageInfo("fr", "fr", "Français")); + options.Languages.Add(new LanguageInfo("hi", "hi", "Hindi", "in")); + options.Languages.Add(new LanguageInfo("it", "it", "Italian", "it")); options.Languages.Add(new LanguageInfo("hu", "hu", "Magyar")); options.Languages.Add(new LanguageInfo("pt-BR", "pt-BR", "Português")); options.Languages.Add(new LanguageInfo("ru", "ru", "Русский")); diff --git a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.HttpApi.HostWithIds/MyProjectNameHttpApiHostModule.cs b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.HttpApi.HostWithIds/MyProjectNameHttpApiHostModule.cs index 8d92823d2b..cd696da65f 100644 --- a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.HttpApi.HostWithIds/MyProjectNameHttpApiHostModule.cs +++ b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.HttpApi.HostWithIds/MyProjectNameHttpApiHostModule.cs @@ -159,6 +159,8 @@ namespace MyCompanyName.MyProjectName options.Languages.Add(new LanguageInfo("en-GB", "en-GB", "English (UK)")); options.Languages.Add(new LanguageInfo("fi", "fi", "Finnish")); options.Languages.Add(new LanguageInfo("fr", "fr", "Français")); + options.Languages.Add(new LanguageInfo("hi", "hi", "Hindi", "in")); + options.Languages.Add(new LanguageInfo("it", "it", "Italian", "it")); options.Languages.Add(new LanguageInfo("hu", "hu", "Magyar")); options.Languages.Add(new LanguageInfo("pt-BR", "pt-BR", "Português")); options.Languages.Add(new LanguageInfo("ru", "ru", "Русский")); diff --git a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.IdentityServer/MyProjectNameIdentityServerModule.cs b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.IdentityServer/MyProjectNameIdentityServerModule.cs index 510358028d..843cf53e47 100644 --- a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.IdentityServer/MyProjectNameIdentityServerModule.cs +++ b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.IdentityServer/MyProjectNameIdentityServerModule.cs @@ -66,6 +66,8 @@ namespace MyCompanyName.MyProjectName options.Languages.Add(new LanguageInfo("en-GB", "en-GB", "English (UK)")); options.Languages.Add(new LanguageInfo("fi", "fi", "Finnish")); options.Languages.Add(new LanguageInfo("fr", "fr", "Français")); + options.Languages.Add(new LanguageInfo("hi", "hi", "Hindi", "in")); + options.Languages.Add(new LanguageInfo("it", "it", "Italian", "it")); options.Languages.Add(new LanguageInfo("hu", "hu", "Magyar")); options.Languages.Add(new LanguageInfo("pt-BR", "pt-BR", "Português")); options.Languages.Add(new LanguageInfo("ru", "ru", "Русский")); diff --git a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Web.Host/Menus/MyProjectNameMenuContributor.cs b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Web.Host/Menus/MyProjectNameMenuContributor.cs index 5bf2fc404f..90fb5595ed 100644 --- a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Web.Host/Menus/MyProjectNameMenuContributor.cs +++ b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Web.Host/Menus/MyProjectNameMenuContributor.cs @@ -5,6 +5,7 @@ using Microsoft.Extensions.DependencyInjection; using MyCompanyName.MyProjectName.Localization; using MyCompanyName.MyProjectName.MultiTenancy; using Volo.Abp.Account.Localization; +using Volo.Abp.Authorization.Permissions; using Volo.Abp.Identity.Web.Navigation; using Volo.Abp.SettingManagement.Web.Navigation; using Volo.Abp.TenantManagement.Web.Navigation; @@ -69,16 +70,11 @@ namespace MyCompanyName.MyProjectName.Web.Menus { var l = context.GetLocalizer(); var accountStringLocalizer = context.GetLocalizer(); - var currentUser = context.ServiceProvider.GetRequiredService(); - var identityServerUrl = _configuration["AuthServer:Authority"] ?? ""; - if (currentUser.IsAuthenticated) - { - context.Menu.AddItem(new ApplicationMenuItem("Account.Manage", accountStringLocalizer["ManageYourProfile"], - $"{identityServerUrl.EnsureEndsWith('/')}Account/Manage?returnUrl={_configuration["App:SelfUrl"]}", icon: "fa fa-cog", order: 1000, null, "_blank")); - context.Menu.AddItem(new ApplicationMenuItem("Account.Logout", l["Logout"], url: "~/Account/Logout", icon: "fa fa-power-off", order: int.MaxValue - 1000)); - } + context.Menu.AddItem(new ApplicationMenuItem("Account.Manage", accountStringLocalizer["ManageYourProfile"], + $"{identityServerUrl.EnsureEndsWith('/')}Account/Manage?returnUrl={_configuration["App:SelfUrl"]}", icon: "fa fa-cog", order: 1000, null, "_blank").RequireAuthenticated()); + context.Menu.AddItem(new ApplicationMenuItem("Account.Logout", l["Logout"], url: "~/Account/Logout", icon: "fa fa-power-off", order: int.MaxValue - 1000).RequireAuthenticated()); return Task.CompletedTask; } diff --git a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Web/MyProjectNameWebModule.cs b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Web/MyProjectNameWebModule.cs index 3c7e861d3b..ad2fbad18d 100644 --- a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Web/MyProjectNameWebModule.cs +++ b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Web/MyProjectNameWebModule.cs @@ -167,6 +167,8 @@ namespace MyCompanyName.MyProjectName.Web options.Languages.Add(new LanguageInfo("hu", "hu", "Magyar")); options.Languages.Add(new LanguageInfo("fi", "fi", "Finnish")); options.Languages.Add(new LanguageInfo("fr", "fr", "Français")); + options.Languages.Add(new LanguageInfo("hi", "hi", "Hindi", "in")); + options.Languages.Add(new LanguageInfo("it", "it", "Italian", "it")); options.Languages.Add(new LanguageInfo("pt-BR", "pt-BR", "Português")); options.Languages.Add(new LanguageInfo("ru", "ru", "Русский")); options.Languages.Add(new LanguageInfo("tr", "tr", "Türkçe")); diff --git a/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.HttpApi.Host/MyProjectNameHttpApiHostModule.cs b/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.HttpApi.Host/MyProjectNameHttpApiHostModule.cs index f0189da922..1a57ba090c 100644 --- a/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.HttpApi.Host/MyProjectNameHttpApiHostModule.cs +++ b/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.HttpApi.Host/MyProjectNameHttpApiHostModule.cs @@ -99,6 +99,8 @@ namespace MyCompanyName.MyProjectName options.Languages.Add(new LanguageInfo("en-GB", "en-GB", "English (UK)")); options.Languages.Add(new LanguageInfo("fi", "fi", "Finnish")); options.Languages.Add(new LanguageInfo("fr", "fr", "Français")); + options.Languages.Add(new LanguageInfo("hi", "hi", "Hindi", "in")); + options.Languages.Add(new LanguageInfo("it", "it", "Italian", "it")); options.Languages.Add(new LanguageInfo("hu", "hu", "Magyar")); options.Languages.Add(new LanguageInfo("pt-BR", "pt-BR", "Português")); options.Languages.Add(new LanguageInfo("ru", "ru", "Русский")); diff --git a/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.IdentityServer/MyProjectNameIdentityServerModule.cs b/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.IdentityServer/MyProjectNameIdentityServerModule.cs index bca9866573..25e9366802 100644 --- a/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.IdentityServer/MyProjectNameIdentityServerModule.cs +++ b/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.IdentityServer/MyProjectNameIdentityServerModule.cs @@ -107,6 +107,8 @@ namespace MyCompanyName.MyProjectName options.Languages.Add(new LanguageInfo("en-GB", "en-GB", "English (UK)")); options.Languages.Add(new LanguageInfo("fi", "fi", "Finnish")); options.Languages.Add(new LanguageInfo("fr", "fr", "Français")); + options.Languages.Add(new LanguageInfo("hi", "hi", "Hindi", "in")); + options.Languages.Add(new LanguageInfo("it", "it", "Italian", "it")); options.Languages.Add(new LanguageInfo("hu", "hu", "Magyar")); options.Languages.Add(new LanguageInfo("pt-BR", "pt-BR", "Português")); options.Languages.Add(new LanguageInfo("ru", "ru", "Русский")); diff --git a/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Web.Host/MyProjectNameWebHostMenuContributor.cs b/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Web.Host/MyProjectNameWebHostMenuContributor.cs index c1151363ab..ef27052921 100644 --- a/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Web.Host/MyProjectNameWebHostMenuContributor.cs +++ b/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Web.Host/MyProjectNameWebHostMenuContributor.cs @@ -5,6 +5,7 @@ using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Localization; using MyCompanyName.MyProjectName.Localization; +using Volo.Abp.Authorization.Permissions; using Volo.Abp.UI.Navigation; using Volo.Abp.Users; @@ -31,30 +32,25 @@ namespace MyCompanyName.MyProjectName private void AddLogoutItemToMenu(MenuConfigurationContext context) { - var currentUser = context.ServiceProvider.GetRequiredService(); var l = context.GetLocalizer(); - if (currentUser.IsAuthenticated) - { - context.Menu.Items.Add(new ApplicationMenuItem( - "Account.Manage", - l["ManageYourProfile"], - $"{_configuration["AuthServer:Authority"].EnsureEndsWith('/')}Account/Manage", - icon: "fa fa-cog", - order: int.MaxValue - 1001, - null, - "_blank") - ); - - - context.Menu.Items.Add(new ApplicationMenuItem( - "Account.Logout", - l["Logout"], - "~/Account/Logout", - "fas fa-power-off", - order: int.MaxValue - 1000 - )); - } + context.Menu.Items.Add(new ApplicationMenuItem( + "Account.Manage", + l["ManageYourProfile"], + $"{_configuration["AuthServer:Authority"].EnsureEndsWith('/')}Account/Manage", + icon: "fa fa-cog", + order: int.MaxValue - 1001, + null, + "_blank" + ).RequireAuthenticated()); + + context.Menu.Items.Add(new ApplicationMenuItem( + "Account.Logout", + l["Logout"], + "~/Account/Logout", + "fas fa-power-off", + order: int.MaxValue - 1000 + ).RequireAuthenticated()); } } } diff --git a/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Web.Unified/MyProjectNameWebUnifiedModule.cs b/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Web.Unified/MyProjectNameWebUnifiedModule.cs index 9775a76173..957c7634bf 100644 --- a/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Web.Unified/MyProjectNameWebUnifiedModule.cs +++ b/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Web.Unified/MyProjectNameWebUnifiedModule.cs @@ -105,6 +105,8 @@ namespace MyCompanyName.MyProjectName options.Languages.Add(new LanguageInfo("en-GB", "en-GB", "English (UK)")); options.Languages.Add(new LanguageInfo("fi", "fi", "Finnish")); options.Languages.Add(new LanguageInfo("fr", "fr", "Français")); + options.Languages.Add(new LanguageInfo("hi", "hi", "Hindi", "in")); + options.Languages.Add(new LanguageInfo("it", "it", "Italian", "it")); options.Languages.Add(new LanguageInfo("hu", "hu", "Magyar")); options.Languages.Add(new LanguageInfo("pt-BR", "pt-BR", "Português (Brasil)")); options.Languages.Add(new LanguageInfo("ru", "ru", "Русский")); diff --git a/templates/module/aspnet-core/src/MyCompanyName.MyProjectName.Domain.Shared/Localization/MyProjectName/hi.json b/templates/module/aspnet-core/src/MyCompanyName.MyProjectName.Domain.Shared/Localization/MyProjectName/hi.json new file mode 100644 index 0000000000..3af7c4a140 --- /dev/null +++ b/templates/module/aspnet-core/src/MyCompanyName.MyProjectName.Domain.Shared/Localization/MyProjectName/hi.json @@ -0,0 +1,7 @@ +{ + "culture": "hi", + "texts": { + "ManageYourProfile": "अपनी प्रोफ़ाइल प्रबंधित करें", + "SamplePageMessage": "MyProjectName मॉड्यूल के लिए एक नमूना पृष्ठ" + } +} \ No newline at end of file diff --git a/templates/module/aspnet-core/src/MyCompanyName.MyProjectName.Domain.Shared/Localization/MyProjectName/it.json b/templates/module/aspnet-core/src/MyCompanyName.MyProjectName.Domain.Shared/Localization/MyProjectName/it.json new file mode 100644 index 0000000000..a0906fe12e --- /dev/null +++ b/templates/module/aspnet-core/src/MyCompanyName.MyProjectName.Domain.Shared/Localization/MyProjectName/it.json @@ -0,0 +1,7 @@ +{ + "culture": "it", + "texts": { + "ManageYourProfile": "Gestisci il tuo profilo", + "SamplePageMessage": "Una pagina di esempio per il modulo MyProjectName" + } +} \ No newline at end of file