Browse Source

Merge remote-tracking branch 'abpframework/dev' into docs

pull/4429/head
liangshiwei 6 years ago
parent
commit
d82b929b86
  1. 156
      abp_io/AbpIoLocalization/AbpIoLocalization/Admin/Localization/Resources/tr.json
  2. 6
      abp_io/AbpIoLocalization/AbpIoLocalization/Base/Localization/Resources/tr.json
  3. 15
      abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/tr.json
  4. 156
      abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/tr.json
  5. 2
      docs/en/Blob-Storing.md
  6. 133
      docs/en/Distributed-Event-Bus-RabbitMQ-Integration.md
  7. 118
      docs/en/Distributed-Event-Bus.md
  8. 3
      docs/en/RabbitMq.md
  9. 8
      docs/en/UI/Angular/Permission-Management.md
  10. 1
      framework/src/Volo.Abp.AspNetCore.Mvc.UI.Packages/Volo/Abp/AspNetCore/Mvc/UI/Packages/Select2/Select2ScriptContributor.cs
  11. 2
      framework/src/Volo.Abp.BlobStoring/Volo/Abp/BlobStoring/DefaultContainer.cs
  12. 15
      framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/Events/Distributed/AbpDistributedEntityEventOptions.cs
  13. 9
      framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/Events/Distributed/AutoEntityDistributedEventSelectorList.cs
  14. 117
      framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/Events/Distributed/AutoEntityDistributedEventSelectorListExtensions.cs
  15. 6
      framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/Events/Distributed/EntityToEtoMapper.cs
  16. 3
      framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/Events/Distributed/EtoMappingDictionary.cs
  17. 2
      framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/Events/Distributed/EtoMappingDictionaryItem.cs
  18. 9
      framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/Events/Distributed/IAutoEntityDistributedEventSelectorList.cs
  19. 74
      framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/Events/EntityChangeEventHelper.cs
  20. 2
      framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/Distributed/AbpDistributedEventBusOptions.cs
  21. 7
      framework/src/Volo.Abp.Localization/Volo/Abp/Localization/Resources/AbpLocalization/tr.json
  22. 22
      framework/test/Volo.Abp.Ddd.Tests/Volo/Abp/Domain/Entities/Events/Distributed/AutoEntityDistributedEventSelectorListExtensions_Tests.cs
  23. 6
      framework/test/Volo.Abp.Emailing.Tests/Volo/Abp/Emailing/Localization/tr.json
  24. 5
      framework/test/Volo.Abp.Localization.Tests/Volo/Abp/Localization/TestResources/Base/CountryNames/tr.json
  25. 7
      framework/test/Volo.Abp.Localization.Tests/Volo/Abp/Localization/TestResources/Base/Validation/tr.json
  26. 6
      framework/test/Volo.Abp.Localization.Tests/Volo/Abp/Localization/TestResources/Source/tr.json
  27. 6
      framework/test/Volo.Abp.Localization.Tests/Volo/Abp/Localization/TestResources/SourceExt/tr.json
  28. 5
      framework/test/Volo.Abp.TestApp/Volo/Abp/TestApp/TestAppModule.cs
  29. 10
      modules/account/src/Volo.Abp.Account.Application.Contracts/Volo/Abp/Account/Localization/Resources/tr.json
  30. 7
      modules/blogging/src/Volo.Blogging.Domain.Shared/Volo/Blogging/Localization/Resources/tr.json
  31. 4
      modules/blogging/src/Volo.Blogging.Domain/Volo/Blogging/BloggingDomainModule.cs
  32. 3
      modules/docs/app/VoloDocs.Web/Localization/Resources/VoloDocs/Web/tr.json
  33. 22
      modules/docs/src/Volo.Docs.Admin.Application.Contracts/Volo/Docs/Admin/Documents/GetAllInput.cs
  34. 12
      modules/docs/src/Volo.Docs.Admin.Application.Contracts/Volo/Docs/Admin/Localization/Resources/Docs/ApplicationContracts/en.json
  35. 16
      modules/docs/src/Volo.Docs.Admin.Application.Contracts/Volo/Docs/Admin/Localization/Resources/Docs/ApplicationContracts/tr.json
  36. 36
      modules/docs/src/Volo.Docs.Admin.Application/Volo/Docs/Admin/Documents/DocumentAdminAppService.cs
  37. 219
      modules/docs/src/Volo.Docs.Admin.Web/Pages/Docs/Admin/Documents/Index.cshtml
  38. 3
      modules/docs/src/Volo.Docs.Admin.Web/Pages/Docs/Admin/Documents/Index.cshtml.cs
  39. 3
      modules/docs/src/Volo.Docs.Admin.Web/Pages/Docs/Admin/Documents/index.css
  40. 71
      modules/docs/src/Volo.Docs.Admin.Web/Pages/Docs/Admin/Documents/index.js
  41. 1
      modules/docs/src/Volo.Docs.Admin.Web/Pages/Docs/Admin/Documents/index.min.css
  42. 6
      modules/docs/src/Volo.Docs.Admin.Web/Pages/Docs/Admin/Documents/index.scss
  43. 8
      modules/docs/src/Volo.Docs.Admin.Web/Volo.Docs.Admin.Web.csproj
  44. 6
      modules/docs/src/Volo.Docs.Admin.Web/compilerconfig.json
  45. 63
      modules/docs/src/Volo.Docs.Admin.Web/compilerconfig.json.defaults
  46. 4
      modules/docs/src/Volo.Docs.Domain/Volo/Docs/DocsDomainModule.cs
  47. 23
      modules/docs/src/Volo.Docs.Domain/Volo/Docs/Documents/IDocumentRepository.cs
  48. 17
      modules/docs/src/Volo.Docs.Domain/Volo/Docs/Localization/Domain/tr.json
  49. 103
      modules/docs/src/Volo.Docs.EntityFrameworkCore/Volo/Docs/Documents/EFCoreDocumentRepository.cs
  50. 124
      modules/docs/src/Volo.Docs.MongoDB/Volo/Docs/Documents/MongoDocumentRepository.cs
  51. 155
      modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/Index.cshtml
  52. 6
      modules/docs/src/Volo.Docs.Web/Pages/Documents/Shared/Scripts/vs.js
  53. 89
      modules/docs/src/Volo.Docs.Web/Pages/Documents/Shared/Styles/vs.css
  54. 2
      modules/docs/src/Volo.Docs.Web/Pages/Documents/Shared/Styles/vs.min.css
  55. 131
      modules/docs/src/Volo.Docs.Web/Pages/Documents/Shared/Styles/vs.scss
  56. 4
      modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/AbpIdentityDomainModule.cs
  57. 9
      modules/identity/test/Volo.Abp.Identity.Domain.Tests/Volo/Abp/Identity/AbpIdentityDomainTestModule.cs
  58. 15
      modules/identity/test/Volo.Abp.Identity.Domain.Tests/Volo/Abp/Identity/Distributed_User_Change_Event_Tests.cs
  59. 4
      modules/identityserver/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/AbpIdentityServerDomainModule.cs
  60. 4
      modules/tenant-management/src/Volo.Abp.TenantManagement.Domain/Volo/Abp/TenantManagement/AbpTenantManagementDomainModule.cs
  61. 12
      modules/virtual-file-explorer/src/Volo.Abp.VirtualFileExplorer.Web/Localization/Resources/tr.json
  62. 7
      npm/ng-packs/packages/core/src/lib/services/list.service.ts
  63. 13
      npm/ng-packs/packages/theme-shared/src/lib/directives/ngx-datatable-list.directive.ts
  64. 1
      samples/MicroserviceDemo/applications/BackendAdminApp.Host/BackendAdminAppHostModule.cs
  65. 6
      samples/MicroserviceDemo/microservices/IdentityService.Host/IdentityServiceHostModule.cs
  66. 10
      samples/MicroserviceDemo/modules/product/src/ProductManagement.Application.Contracts/ProductManagement/Localization/ApplicationContracts/tr.json
  67. 16
      samples/MicroserviceDemo/modules/product/src/ProductManagement.Web/Localization/Resources/ProductManagement/tr.json

156
abp_io/AbpIoLocalization/AbpIoLocalization/Admin/Localization/Resources/tr.json

@ -1,5 +1,161 @@
{
"culture": "tr",
"texts": {
"Permission:Organizations": "Organizasyonlar",
"Permission:Manage": "Organizasyonları Yönet",
"Permission:DiscountRequests": "İndirim Talepleri",
"Permission:DiscountManage": "İndirim Taleplerini Yönet",
"Permission:Disable": "Devre Dışı Bırak",
"Permission:Enable": "Etkinleşir",
"Permission:EnableSendEmail": "E-Posta Göndermeyi Etkinleştir",
"Permission:SendEmail": "E-Posta Gönder",
"Permission:NpmPackages": "NPM Paketleri",
"Permission:NugetPackages": "Nuget Paketleri",
"Permission:Maintenance": "Bakım",
"Permission:Maintain": "Bakım Yap",
"Permission:ClearCaches": "Önbelleği temizle",
"Permission:Modules": "Modüller",
"Permission:Packages": "Paketler",
"Permission:Edit": "Güncelle",
"Permission:Delete": "Sil",
"Permission:Create": "Oluştur",
"Permission:Accounting": "Muhasebe",
"Permission:Accounting:Quotation": "Fiyatlandırma",
"Permission:Accounting:Invoice": "Fatura",
"Menu:Organizations": "Organizasyonlar",
"Menu:Accounting": "Muhasebe",
"Menu:Packages": "Paketler",
"Menu:DiscountRequests": "İndirim Talepleri",
"NpmPackageDeletionWarningMessage": "Bu NPM Paketi silinecektir. Onaylıyor musunuz?",
"NugetPackageDeletionWarningMessage": "Bu Nuget Paketi silinecektir. Onaylıyor musunuz?",
"ModuleDeletionWarningMessage": "Bu Modül silinecektir. Onaylıyor musunuz?",
"Name": "İsim",
"DisplayName": "Görüntülenen isim",
"ShortDescription": "Kısa açıklama",
"NameFilter": "İsim",
"CreationTime": "Oluşturma zamanı",
"IsPro": "Is pro",
"ShowOnModuleList": "Modül listesinde göster",
"EfCoreConfigureMethodName": "Metot adını yapılandır",
"IsProFilter": "Is pro",
"ApplicationType": "Uygulama tipi",
"Target": "Hedef",
"TargetFilter": "Hedef",
"ModuleClass": "Modül sınıfı",
"NugetPackageTarget.DomainShared": "Domain Shared",
"NugetPackageTarget.Domain": "Domain",
"NugetPackageTarget.Application": "Application",
"NugetPackageTarget.ApplicationContracts": "Application Contracts",
"NugetPackageTarget.HttpApi": "Http Api",
"NugetPackageTarget.HttpApiClient": "Http Api Client",
"NugetPackageTarget.Web": "Web",
"NugetPackageTarget.EntityFrameworkCore": "DeleteAllEntityFramework Core",
"NugetPackageTarget.MongoDB": "MongoDB",
"Edit": "Güncelle",
"Delete": "Sil",
"Refresh": "Yenile",
"NpmPackages": "NPM Paketleri",
"NugetPackages": "Nuget Paketleri",
"NpmPackageCount": "NPM Paket Sayısı",
"NugetPackageCount": "Nuget Paket Sayısı",
"Module": "Modüller",
"ModuleInfo": "Modül bilgisi",
"CreateANpmPackage": "Bir NPM paketi oluştur",
"CreateAModule": "Bir modül oluştur",
"CreateANugetPackage": "Bir Nuget paketi oluştur",
"AddNew": "Yenisini Ekle",
"PackageAlreadyExist{0}": "\"{0}\"isimli paket zaten eklendi.",
"ModuleAlreadyExist{0}": "\"{0}\" isimli modül zaten eklendi.",
"ClearCache": "Önbelleği Temizle",
"SuccessfullyCleared": "Başarıyla temizlendi",
"Menu:NpmPackages": "NPM Paketleri",
"Menu:Modules": "Modüller",
"Menu:Maintenance": "Bakım",
"Menu:NugetPackages": "Nuget Paketleri",
"CreateAnOrganization": "Bir organizasyon oluştur",
"Organizations": "Organizasyonlar",
"LongName": "Uzun isim",
"LicenseType": "Lisans tipi",
"MissingLicenseTypeField": "Lisans tipi alanı zorunludur.",
"LicenseStartTime": "Lisans başlama zamanı",
"LicenseEndTime": "Lisans bitiş zamanı",
"AllowedDeveloperCount": "İzin verilen developer sayısı",
"UserNameOrEmailAddress": "Kullanıcı adı veya e-posta adresi",
"AddOwner": "Owner ekle",
"UserName": "Kullanıcı Adı",
"Email": "E-Posta",
"Developers": "Developers",
"AddDeveloper": "Developer Ekle",
"Create": "Oluştur",
"UserNotFound": "Kullanıcı bulunamadı",
"{0}WillBeRemovedFromDevelopers": "{0} kullanıcı adlı developer silinecektir, Onaylıyor musunuz?",
"{0}WillBeRemovedFromOwners": "{0} kullanıcı adlı owner silinecektir, Onaylıyor musunuz?",
"Computers": "Bilgisayarlar",
"UniqueComputerId": "Özgün bilgisayar id",
"LastSeenDate": "Son görülme tarihi",
"{0}Computer{1}WillBeRemovedFromRecords": "{0} kullanıcı isimli kullanıcının bilgisayarı ({1}) kayıtlardan kaldırılacaktır",
"OrganizationDeletionWarningMessage": "Organizasyon silinecektir.",
"DeletingLastOwnerWarningMessage": "Bir organizasyon en az bir ownera sahip olmalıdır! Bu nedenle bu ownerı kaldıramazsınız",
"This{0}AlreadyExistInThisOrganization": "{0} zaten bu organizasyonda bulunmaktadır",
"AreYouSureYouWantToDeleteAllComputers": "Tüm bilgisayaları silmek istediğinize emin misiniz?",
"DeleteAll": "Tümünü sil",
"DoYouWantToCreateNewUser": "Yeni kullanıcı oluşturmak istiyor musunuz?",
"MasterModules": "Master Modüller",
"OrganizationName": "Organizasyon adı",
"OrganizationNamePlaceholder": "Organizasyon adı...",
"UsernameOrEmail": "Kullanıcı adı veya e-posta",
"UsernameOrEmailPlaceholder": "Kullanıcı adı veya e-posta",
"Member": "Üye",
"PurchaseOrderNo": "Satın alma sipariş no",
"QuotationDate": "Fiyatlandırma tarihi",
"CompanyName": "Şirket adı",
"CompanyAddress": "Şirket adresi",
"Price": "Fiyat",
"DiscountText": "İndirim metni",
"DiscountQuantity": "İndirim miktarı",
"DiscountPrice": "İndirim fiyatı",
"Quotation": "Fiyatlandırma",
"ExtraText": "Eksta metin",
"ExtraAmount": "Eksta miktar",
"DownloadQuotation": "Fiyatlandırmayı İndir",
"Invoice": "Fatura",
"TaxNumber": "Vergi Numarası",
"InvoiceNumber": "Fatura Numarası",
"InvoiceDate": "Fatura Tarihi",
"InvoiceNote": "Fatura Notu",
"Quantity": "Miktar",
"AddProduct": "Ürün Ekle",
"AddProductWarning": "Ürün eklemelisiniz!",
"TotalPrice": "Toplam Fiyat",
"Generate": "Üret",
"MissingQuantityField": "Miktar alanı zorunludur!",
"MissingPriceField": "Fiyat alanı zorunludur!",
"CodeUsageStatus": "Statü",
"Country": "Ülke",
"DeveloperCount": "Developer Sayısı",
"RequestCode": "Talep Kodu",
"WebSite": "Web Sitesi",
"GithubUsername": "Github Kullanıcı adı",
"PhoneNumber": "Telefon Numarası",
"ProjectDescription": "Proje Açıklaması",
"Referrer": "Yönlendiren",
"DiscountRequests": "İndirim Talebi",
"Copylink": "Kopyalama Linki",
"Disable": "Devre Dışı Bırak",
"Enable": "Etkinleştir",
"EnableSendEmail": "E-Posta Göndermeyi Etkinleştir",
"SendEmail": "E-Posta Gönder",
"SuccessfullyDisabled": "Başarıyla Devre Dışı Bırakıldı",
"SuccessfullyEnabled": "Başarıyla Etkinleştirildi",
"EmailSent": "E-Posta Gönderildi",
"SuccessfullySent": "Başarıyla Gönderildi",
"SuccessfullyDeleted": "Başarıyla Silindi",
"DiscountRequestDeletionWarningMessage": "İndirim talebi silinecektir",
"BusinessType": "İş tipi",
"TotalQuestionCount": "Toplam soru sayısı",
"RemainingQuestionCount": "Kalan soru sayısı",
"TotalQuestionMustBeGreaterWarningMessage": "Toplam soru sayısı kalan soru sayısından büyük olmalıdır!",
"QuestionCountsMustBeGreaterThanZero": "Toplam soru sayısı ve kalan soru sayısı sıfır veya sıfırdan daha büyük olmalıdır!",
"UnlimitedQuestionCount": "Sınırsız soru sayısı"
}
}

6
abp_io/AbpIoLocalization/AbpIoLocalization/Base/Localization/Resources/tr.json

@ -1,4 +1,4 @@
{
{
"culture": "tr",
"texts": {
"Volo.AbpIo.Domain:010004": "Maksimum üye sayısı aşıldı!",
@ -18,12 +18,14 @@
"ReadyToGetStarted?": "Başlamaya hazır mısın?",
"JoinOurCommunity": "Topluluğumuza katılın",
"GetStartedUpper": "BAŞLAYIN",
"ForkMeOnGitHub": "Fork me on GitHub",
"Features": "Özellikler",
"GetStarted": "Başlayın",
"Documents": "Dokümanlar",
"Community": "Topluluk",
"ContributionGuide": "Katkı Rehberi",
"Blog": "Blog",
"Commercial": "Ticari",
"SeeDocuments": "Dokümanlara Göz Atın"
}
}
}

15
abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/tr.json

@ -1,4 +1,4 @@
{
{
"culture": "tr",
"texts": {
"OrganizationManagement": "Organizasyon yönetimi",
@ -6,6 +6,8 @@
"Volo.AbpIo.Commercial:010003": "Bu organizasyonda yetkili değilsiniz!",
"OrganizationNotFoundMessage": "Organizasyon bulunamadı!",
"DeveloperCount": "Yazılımcı sayısı",
"QuestionCount": "Kalan / toplam sorular",
"Unlimited": "Sınırsız",
"Owners": "Yetkili sayısı",
"AddMember": "Üye ekle",
"AddOwner": "Yetkili ekle",
@ -19,12 +21,15 @@
"StartDate": "Başlangıç tarihi",
"EndDate": "bitiş tarihi",
"Modules": "Modüller",
"Volo.AbpIo.Commercial:010004": "Kullanıcı bulunamadı! İlgili kullanıcının daha önceden sisteme kayıt olmuş olması gerekiyor.",
"LicenseExtendMessage": "Lisans bitiş tarihiniz {0} tarihine kadar uzatıldı",
"LicenseUpgradeMessage": "Lisansınız {0} lisansa yükseltildi",
"LicenseAddDeveloperMessage": "Lisansınıza {0} geliştirici eklendi",
"MyOrganizations": "Organizasyonlarım",
"ApiKey": "API anahtarı",
"UserNameNotFound": "{0} kullanıcı adı ile bir kullanıcı yok"
"Volo.AbpIo.Commercial:010004": "Kullanıcı bulunamadı! İlgili kullanıcının daha önceden sisteme kayıt olmuş olması gerekiyor.",
"MyOrganizations": "Organizasyonlarım",
"ApiKey": "API anahtarı",
"UserNameNotFound": "{0} kullanıcı adı ile bir kullanıcı yok",
"SuccessfullyAddedToNewsletter": "Bültenimize abone olduğunuz için teşekkürler!",
"MyProfile": "Profilim",
"EmailNotValid": "Lütfen uygun bir e-posta adresi giriniz"
}
}

156
abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/tr.json

@ -1,5 +1,161 @@
{
"culture": "tr",
"texts": {
"GetStarted": "Başlamak - Başlangıç Templateleri",
"Create": "Oluştur",
"NewProject": "Yeni Proje",
"DirectDownload": "Doğrudan İndir",
"ProjectName": "Proje ismi",
"ProjectType": "Proje tipi",
"DatabaseProvider": "Veritabanı sağlayacısı",
"NTier": "N-Tier",
"IncludeUserInterface": "Kullanıcı arayüzünü dahil et",
"CreateNow": "Şimdi oluştur",
"TheStartupProject": "Başlangıç projesi",
"Tutorial": "Öğretici",
"UsingCLI": "CLI Kullanmak",
"SeeDetails": "Detayları Görüntüle",
"AbpShortDescription": "ABP modern web uygulamaları geliştirmek için eksiksiz bir mimari ve günlü bir altyapıdır! Size SOLID geliştirme tecrübelerini sunmak için en iyi uygulama ve kuralları takip eder.",
"SourceCodeUpper": "KAYNAK KOD",
"LatestReleaseLogs": "Son release kayıtları",
"Infrastructure": "Altyapı",
"Architecture": "Mimari",
"Modular": "Modüler",
"DontRepeatYourself": "Kendini Tekrar Etme",
"DeveloperFocused": "Developer Odaklı",
"FullStackApplicationInfrastructure": "Full stack uygulama altyapısı",
"DomainDrivenDesign": "Domain Driven Design",
"DomainDrivenDesignExplanation": "DDD paterni ve prensiplerinden yola çıkarak dizayn edildi ve geliştirildi. Uygulamanız için katmanlı bir model sunmaktadır.",
"Authorization": "Yetkilendirme",
"AuthorizationExplanation": "Kullanıcı, rol ve ayrıntılı izin sistemi ile modern yetkilendirme. Microsoft Identity library üzerine kurulmuştur.",
"MultiTenancy": "Multi-Tenancy",
"MultiTenancyExplanationShort": "SaaS uygulamaları kolaylaştı! Veritababından kullanıcı arayüzüne entegre edilmiş multi-tenancy",
"CrossCuttingConcerns": "Cross Cutting Concerns",
"CrossCuttingConcernsExplanationShort": "Yetkilendirme, validasyon, hata yakalama, caching, audit logging, işlem yönetimi ve bunun gibi konular için eksiksiz altyapı.",
"BuiltInBundlingMinification": "Hazır Paketleme & Küçültme",
"BuiltInBundlingMinificationExplanation": "Paketleme ve küçültmek için external araçları kullanmayı bırakın. ABP daha basit, dinamik, güçlü, modüler ve hazır yolları öneriyor.",
"VirtualFileSystem": "Sanal Dosya Sistemi",
"VirtualFileSystemExplanation": "Sayfaları, scriptleri, stilleri, resimleri... paketlere/kütüpanelere gömün ve farklı uygulamalarda yeniden kullanın. ",
"Theming": "Theming",
"ThemingExplanationShort": "Bootstrap tabanlı standart kullanıcı arayüzlerini kullan ve kişiselleştir veya kendin yeni bir tane oluştur.",
"BootstrapTagHelpersDynamicForms": "Bootstrap Tag Helpers & Dinamik Formlar",
"BootstrapTagHelpersDynamicFormsExplanation": "Bootstrap komponentlerinin tekrar eden detaylarını manuel olarak yazmak yerine, Bu işlemi basitleştirmek ve iyileştirme avantajından faydalanmak için ABP'nin tag helperlarını kullanın. Dinamik form bir C# sınıfından model olarak eksiksik form oluşturabilir.",
"HTTPAPIsDynamicProxies": "HTTP APIs & Dynamic Proxies",
"HTTPAPIsDynamicProxiesExplanation": "Application servislerini otomatik olarak Rest stil Http API olarak ayarlayın ve dinamaik Javascript & C# proxyler ile kullanın.",
"CompleteArchitectureInfo": "Bakım yapılabilir yazılım çözümleri üretmek için modern mimari.",
"DomainDrivenDesignBasedLayeringModelExplanation": "DDD tabanlı bir katmanlı mimari geliştirmek ve bakım yapılabilir bir kod altyapısı inşaa etmek için size yardım eder.",
"DomainDrivenDesignBasedLayeringModelExplanationCont": "DDD patern ve prensiplerinden yola çıkarak uygulamanızı geliştirmeye yardımcı olmak için başlanıç templateler, soyutlamalar, base sınıflar, servisler, dokümantasyon ve rehberlik sağlar. ",
"MicroserviceCompatibleModelExplanation": "Core framework & pre-build modüller mikroservis mimari göz önünde bulundurularak dizayn edildi.",
"MicroserviceCompatibleModelExplanationCont": "Microservice çözümlerini daha kolay geliştirmek için altyapı, entegrasyon, örnekler ve dokümantasyon sunarken eğer bir tek parça uygulama istiyorsanız ek karmaşıklık getirmez.",
"ModularInfo": "ABP yeniden kullanılabilir uygulama modülleri geliştirebilmenize izin veren eksiksiz modüler sistem sunar.",
"PreBuiltModulesThemes": "Pre-Built Modüller & Temalar",
"PreBuiltModulesThemesExplanation": "Açık kaynak ve ticari modüller & temalar iş uygulamanızda kullanıma hazırdır.",
"NuGetNPMPackages": "NUGET & NPM Packages",
"NuGetNPMPackagesExplanation": "NUGET & NPM paketleri olarak dağıtılmıştır. Yüklemek ve güncellemek kolaydır.",
"ExtensibleReplaceable": "Genişletilebilir/Değiştirilebilir",
"ExtensibleReplaceableExplanation": "Tüm sevisler & modüller genişletilebilirlik göz önünde bulundurularak dizayn edildi. Servislerin, sayfaların stillerin, komponentlerin vb. yerlerini değiştirebilirsizinz.",
"CrossCuttingConcernsExplanation2": "Kodunu daha temiz tut ve kendi uygulama koduna odaklan.",
"CrossCuttingConcernsExplanation3": "Ortak uygulama isterlerini tekrar ve tekrar geliştirmek için zaman harcamayın.",
"AuthenticationAuthorization": "Kimlik Doğrulama & Yetkilendirme",
"ExceptionHandling": "Hata yakalama",
"Validation": "Validasyon",
"DatabaseConnection": "Veritabanı bağlantısı",
"TransactionManagement": "İşlem yönetimi",
"AuditLogging": "Audit Logging",
"Caching": "Caching",
"Multitenancy": "Multitenancy",
"DataFiltering": "Date filtreleme",
"ConventionOverConfiguration": "Yapılandırma Üzerinde Kurallar",
"ConventionOverConfigurationExplanation": "ABP minimal veya sıfır yapılandırma ile ortak uygulama kurallarını varsayılan olarak uygular.",
"ConventionOverConfigurationExplanationList1": "Dependency injection için bilinen servisler otomatik olarak kaydedilir.",
"ConventionOverConfigurationExplanationList2": "Application servisler isimlerdirme kuralları ile HTTP API ler olarak uygulanır.",
"ConventionOverConfigurationExplanationList3": "C# ve JavaScript için dinamik HTTP istemci proxyleri yaratır.",
"ConventionOverConfigurationExplanationList4": "Entityleriniz için varsayılaan repositoriler sunar.",
"ConventionOverConfigurationExplanationList5": "Her web request veya application servis metodu için Unit of Work işlemini yönetir.",
"ConventionOverConfigurationExplanationList6": "Entityleriniz için oluşturma, güncelleme & silme işlemlerini yayınlar.",
"BaseClasses": "Ana Sınıflar",
"BaseClassesExplanation": "Ortak uygulama paternleri için pre-built ana sınıflar.",
"DeveloperFocusedExplanation": "ABP developerlar içindir.",
"DeveloperFocusedExplanationCont": "İhtiyacınız olduğunda düşük seviyede çalışmanızı kısıtlamadan günlük yazılım geliştirmenizi basitleştirmeyi amaçlar.",
"SeeAllFeatures": "Tüm Özellikleri Görüntüle",
"CLI_CommandLineInterface": "CLI (Command Line Interface)",
"CLI_CommandLineInterfaceExplanation": "CLI yeni proje oluşturma ve uygulamanıza modüller ekleme işlemlerini otomatik hale getirir.",
"StartupTemplates": "Başlangıç Templateler",
"StartupTemplatesExplanation": "Çeşitli başlangıç templateleri size geliştirme başlatmak için tam yapılandırılmış bir çözüm sağlar.",
"BasedOnFamiliarTools": "Bilinen Araçlara Dayalı ",
"BasedOnFamiliarToolsExplanation": "Zaten bildiğiniz popüler araçlar ile geliştirilme ve egtegre edilmiştir. Düşük öğrenme eğrisi, koaly adaptasyon, rahat geliştirme.",
"ORMIndependent": "ORM Bağımsız",
"ORMIndependentExplanation": "",
"Features": "ABP Framework Özelliklerini Keşfet",
"ABPCLI": "ABP CLI",
"Modularity": "Modülerlik",
"BootstrapTagHelpers": "Bootstrap Tag Helpers",
"DynamicForms": "Dinamik Formlar",
"BundlingMinification": "Paketleme & Küçültme",
"BackgroundJobs": "Arkaplan İşleri",
"DDDInfrastructure": "DDD altyapısı",
"DomainDrivenDesignInfrastructure": "Domain Driven Design Altyapısı",
"AutoRESTAPIs": "Otomatik REST APIler",
"DynamicClientProxies": "Dinamik Client Proxies",
"DistributedEventBus": "Dağıtılmış Event Bus",
"DistributedEventBusWithRabbitMQIntegration": "RabbitMQ Entegrasyonu ile Dağıtılmış Event Bus",
"TestInfrastructure": "Test ALtyapısı",
"AuditLoggingEntityHistories": "Audit Logging & Entity Histories",
"ObjectToObjectMapping": "Object to Object Mapping",
"EmailSMSAbstractions": "E-Posta & SMS Soyutlamaları",
"EmailSMSAbstractionsWithTemplatingSupport": "Template Destekli E-Posta & SMS Soyutlamaları",
"Localization": "Localization",
"SettingManagement": "Ayar Yönetimi",
"ExtensionMethods": "Extension Methods",
"ExtensionMethodsHelpers": "Extension Methods & Helpers",
"AspectOrientedProgramming": "Aspect Oriented Programming",
"DependencyInjection": "Dependency Injection",
"DependencyInjectionByConventions": "Dependency Injection by Conventions",
"ABPCLIExplanation": "ABP CLI (Command Line Interface) ABP tabanlı çözümler ortak işlemleri gerçekleştiren bir komut satırı aracıdır.",
"ModularityExplanation": "ABP, entityleri, servisleri, veritabanı entegrasyonu, APIleri, UI komponentleri ve bunun gibi özelliklere sahip olabilecek kendi uygulama modüllerini geliştirmeniz için eksiksiz bir altyapı sağlar. ",
"MultiTenancyExplanation": "ABP framework sadece multi-tenant uygulama geliştirmenizi desteklemekle kalmaz aynı zamanda kodunuzun çoğunlukla tenantların birbirinden haberi olmaycak şekilde olmasını sağlar.",
"MultiTenancyExplanation2": "Anlık tenant'ı otomatik olarak belirleybilir, farklı tenantların verilerini birbirlerinden izole edebilir.",
"MultiTenancyExplanation3": "Tek bir veritabanını, her tenant için ayrı bir veritabanını ve hibrid yaklaşımları destekler.",
"MultiTenancyExplanation4": "Sen kendi uygulama kodunu odaklan ve bırak framework sizin adınıza multi-tenancy üstesinden gelsin.",
"BootstrapTagHelpersExplanation": "Bootstrap komponentlerinin tekrar eden detaylarını manuel olarak yazmak yerine, Bu işlemi basitleştirmek ve iyileştirme avantajından faydalanmak için ABP'nin tag helperlarını kullanın. Dinamik form bir C# sınıfından model olarak eksiksik form oluşturabilir.",
"DynamicFormsExplanation": "Dinamik form & input tag helpers bir C# sınıfından model olarak eksiksik form oluşturabilir.",
"AuthenticationAuthorizationExplanation": "ASP.NET Core Identity & IdentityServer4 ile entegre edilmiş zengin kimlik doğrulama ve yetkilendirme opsiyonları. Genişletilebilir ve detaylandırılabilr bir izin sistemi sunar.",
"CrossCuttingConcernsExplanation": "Tüm bu ortak şeyleri geliştirmek için kendini sürekli tekrar etme. Kendi iş koduna odaklan ve bırak ABP bunları kurallar ile otomatik hale getirsin.",
"DatabaseConnectionTransactionManagement": "Veritabanı Bğlantısı & İşlem Yönetimi",
"CorrelationIdTracking": "Correlation-Id Tracking",
"BundlingMinificationExplanation": "ABP daha basit, dinamik, güçlü, modüler ve hazır paketlenmiş ve küçültülmüş sistemi öneriyor.",
"VirtualFileSystemnExplanation": "Sanal Dosya Sistemi fiziksel olarak disk üzerinde var olmayan dosyalarını yönetmeyi mümkün kılmaktadır. Bunlar genellikle önceden assemblyler içerisinde gömülü olan(js,css,image,cshtml..) dosyalardır ve bunlar fiziksel dosylar gibi runtimeda kullanılır.",
"ThemingExplanation": "Theming sistem son Bootstrap Framework tabanlı ortak bir kütüphane ve layout tanımlayarak uygulamanızı & modüllerini bağımsız olarak geliştirmenizi sağlamaktadır.",
"DomainDrivenDesignInfrastructureExplanation": "Domain Driven Design pattern ve prensiplerine dayalı katmanlı uygulama geliştirmek için eksiksiz bit altyapı",
"Specification": "Specification",
"Repository": "Repository",
"DomainService": "Domain Service",
"ValueObject": "Value Object",
"ApplicationService": "Application Service",
"DataTransferObject": "Data Transfer Object",
"AggregateRootEntity": "Aggregate Root, Entity",
"AutoRESTAPIsExplanation": "ABP, application servislerinizi otomatik olarak API Controller olarak kurallı bir şekilde yapılandırabilir.",
"DynamicClientProxiesExplanation": "Apilerinizi, JavaScript ve C# clients tarafından kolaylıkla kullanın.",
"DistributedEventBusWithRabbitMQIntegrationExplanation": "Easily publish & consume distributed events using built-in Distributed Event Bus with RabbitMQ integration available.",
"TestInfrastructureExplanation": "The framework has been developed unit & integration testing in mind. Provides you base classes to make it easier. Startup templates come with pre-configured for testing.",
"AuditLoggingEntityHistoriesExplanation": "",
"EmailSMSAbstractionsWithTemplatingSupportExplanation": "",
"LocalizationExplanation": "",
"SettingManagementExplanation": "",
"ExtensionMethodsHelpersExplanation": "",
"AspectOrientedProgrammingExplanation": "",
"DependencyInjectionByConventionsExplanation": "",
"DataFilteringExplanation": "",
"PublishEvents": "Publish Events",
"HandleEvents": "Handle Events",
"AndMore": "",
"Code": "Code",
"Result": "Sonuç",
"SeeTheDocumentForMoreInformation": "See the <a href=\"{1}\">{0} document</a> for more information",
"IndexPageHeroSection": "<span class=\"first-line shine\"><strong>open source</strong></span><span class=\"second-line text-uppercase\">Web Application<br />Framework </span><span class=\"third-line shine2\"><strong>for asp.net core</strong></span>",
"UiFramework": "UI Framework",
"EmailAddress": "E-Posta Adresi",
"Mobile": "Mobil",
"ReactNative": "React Native"
}
}

2
docs/en/Blob-Storing.md

@ -169,7 +169,7 @@ public class ProfileAppService : ApplicationService
If you don't use the generic argument and directly inject the `IBlobContainer` (as explained before), you get the default container. Another way of injecting the default container is using `IBlobContainer<DefaultContainer>`, which returns exactly the same container.
The name of the default container is `Default`.
The name of the default container is `default`.
### Named Containers

133
docs/en/Distributed-Event-Bus-RabbitMQ-Integration.md

@ -1,3 +1,134 @@
# Distributed Event Bus RabbitMQ Integration
TODO
> This document explains **how to configure the [RabbitMQ](https://www.rabbitmq.com/)** as the distributed event bus provider. See the [distributed event bus document](Distributed-Event-Bus.md) to learn how to use the distributed event bus system
## Installation
Use the ABP CLI to add [Volo.Abp.EventBus.RabbitMQ](https://www.nuget.org/packages/Volo.Abp.EventBus.RabbitMQ) NuGet package to your project:
* Install the [ABP CLI](https://docs.abp.io/en/abp/latest/CLI) if you haven't installed before.
* Open a command line (terminal) in the directory of the `.csproj` file you want to add the `Volo.Abp.EventBus.RabbitMQ` package.
* Run `abp add-package Volo.Abp.EventBus.RabbitMQ` command.
If you want to do it manually, install the [Volo.Abp.EventBus.RabbitMQ](https://www.nuget.org/packages/Volo.Abp.EventBus.RabbitMQ) NuGet package to your project and add `[DependsOn(typeof(AbpEventBusRabbitMqModule))]` to the [ABP module](Module-Development-Basics.md) class inside your project.
## Configuration
You can configure using the standard [configuration system](Configuration.md), like using the `appsettings.json` file, or using the [options](Options.md) classes.
### `appsettings.json` file configuration
This is the simplest way to configure the RabbitMQ settings. It is also very strong since you can use any other configuration source (like environment variables) that is [supported by the AspNet Core](https://docs.microsoft.com/en-us/aspnet/core/fundamentals/configuration/).
**Example: The minimal configuration to connect to a local RabbitMQ server with default configurations**
````json
{
"RabbitMQ": {
"EventBus": {
"ClientName": "MyClientName",
"ExchangeName": "MyExchangeName"
}
}
}
````
* `ClientName` is the name of this application, which is used as the **queue name** on the RabbitMQ.
* `ExchangeName` is the **exchange name**.
See [the RabbitMQ document](https://www.rabbitmq.com/dotnet-api-guide.html#exchanges-and-queues) to understand these options better.
#### Connections
If you need to connect to another server than the localhost, you need to configure the connection properties.
**Example: Specify the host name (as an IP address)**
````json
{
"RabbitMQ": {
"Connections": {
"Default": {
"HostName": "123.123.123.123"
}
},
"EventBus": {
"ClientName": "MyClientName",
"ExchangeName": "MyExchangeName"
}
}
}
````
Defining multiple connections is allowed. In this case, you can specify the connection that is used for the event bus.
**Example: Declare two connections and use one of them for the event bus**
````json
{
"RabbitMQ": {
"Connections": {
"Default": {
"HostName": "123.123.123.123"
},
"SecondConnection": {
"HostName": "321.321.321.321"
}
},
"EventBus": {
"ClientName": "MyClientName",
"ExchangeName": "MyExchangeName",
"ConnectionName": "SecondConnection"
}
}
}
````
This allows you to use multiple RabbitMQ server in your application, but select one of them for the event bus.
You can use any of the [ConnectionFactry](http://rabbitmq.github.io/rabbitmq-dotnet-client/api/RabbitMQ.Client.ConnectionFactory.html#properties) properties as the connection properties.
**Example: Specify the connection port**
````csharp
{
"RabbitMQ": {
"Connections": {
"Default": {
"HostName": "123.123.123.123",
"Port": "5672"
}
}
}
}
````
### The Options Classes
`AbpRabbitMqOptions` and `AbpRabbitMqEventBusOptions` classes can be used to configure the connection strings and event bus options for the RabbitMQ.
You can configure this options inside the `ConfigureServices` of your [module](Module-Development-Basics.md).
**Example: Configure the connection**
````csharp
Configure<AbpRabbitMqOptions>(options =>
{
options.Connections.Default.UserName = "user";
options.Connections.Default.Password = "pass";
options.Connections.Default.HostName = "123.123.123.123";
options.Connections.Default.Port = 5672;
});
````
**Example: Configure the client and exchange names**
````csharp
Configure<AbpRabbitMqEventBusOptions>(options =>
{
options.ClientName = "TestApp1";
options.ExchangeName = "TestMessages";
});
````
Using these options classes can be combined with the `appsettings.json` way. Configuring an option property in the code overrides the value in the configuration file.

118
docs/en/Distributed-Event-Bus.md

@ -179,3 +179,121 @@ That's all.
You can inject any service and perform any required logic here. A single event handler class can **subscribe to multiple events** but implementing the `IDistributedEventHandler<TEvent>` interface for each event type.
> The handler class must be registered to the dependency injection (DI). The sample above uses the `ITransientDependency` to accomplish it. See the [DI document](Dependency-Injection.md) for more options.
## Pre-Defined Events
ABP Framework **automatically publishes** distributed events for **create, update and delete** operations for an [entity](Entities.md) once you configure it.
### Event Types
There are three pre-defined event types:
* `EntityCreatedEto<T>` is published when an entity of type `T` was created.
* `EntityUpdatedEto<T>` is published when an entity of type `T` was updated.
* `EntityDeletedEto<T>` is published when an entity of type `T` was deleted.
These types are generics. `T` is actually the type of the **E**vent **T**ransfer **O**bject (ETO) rather than the type of the entity. Because, an entity object can not be transferred as a part of the event data. So, it is typical to define a ETO class for an entity class, like `ProductEto` for `Product` entity.
### Subscribing to the Events
Subscribing to the auto events is same as subscribing a regular distributed event.
**Example: Get notified once a product updated**
````csharp
using System.Threading.Tasks;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Domain.Entities.Events.Distributed;
using Volo.Abp.EventBus.Distributed;
namespace AbpDemo
{
public class MyHandler :
IDistributedEventHandler<EntityUpdatedEto<ProductEto>>,
ITransientDependency
{
public async Task HandleEventAsync(EntityUpdatedEto<ProductEto> eventData)
{
var productId = eventData.Entity.Id;
//TODO
}
}
}
````
* `MyHandler` implements the `IDistributedEventHandler<EntityUpdatedEto<ProductEto>>`.
### Configuration
You can configure the `AbpDistributedEntityEventOptions` in the `ConfigureServices` of your [module](Module-Development-Basics.md) to add a selector.
**Example: Configuration samples**
````csharp
Configure<AbpDistributedEntityEventOptions>(options =>
{
//Enable for all entities
options.AutoEventSelectors.AddAll();
//Enable for a single entity
options.AutoEventSelectors.Add<IdentityUser>();
//Enable for all entities in a namespace (and child namespaces)
options.AutoEventSelectors.AddNamespace("Volo.Abp.Identity");
//Custom predicate expression that should return true to select a type
options.AutoEventSelectors.Add(
type => type.Namespace.StartsWith("MyProject.")
);
});
````
* The last one provides flexibility to decide if the events should be published for the given entity type. Returns `true` to accept a `Type`.
You can add more than one selector. If one of the selectors match for an entity type, then it is selected.
### Event Transfer Object
Once you enable **auto events** for an entity, ABP Framework starts to publish events on the changes on this entity. If you don't specify a corresponding **E**vent **T**ransfer **O**bject (ETO) for the entity, ABP Framework uses a standard type, named `EntityEto`, which has only two properties:
* `EntityType` (`string`): Full name (including namespace) of the entity class.
* `KeysAsString` (`string`): Primary key(s) of the changed entity. If it has a single key, this property will be the primary key value. For a composite key, it will contain all keys separated by `,` (comma).
So, you can implement the `IDistributedEventHandler<EntityUpdatedEto<EntityEto>>` to subscribe the events. However, it is not a good approach to subscribe to such a generic event. You can define the corresponding ETO for the entity type.
**Example: Declare to use `ProductEto` for the `Product` entity**
````csharp
Configure<AbpDistributedEntityEventOptions>(options =>
{
options.AutoEventSelectors.Add<Product>();
options.EtoMappings.Add<Product, ProductEto>();
});
````
This example;
* Adds a selector to allow to publish the create, update and delete events for the `Product` entity.
* Configure to use the `ProductEto` as the event transfer object to publish for the `Product` related events.
Distributed event system use the [object to object mapping](Object-To-Object-Mapping.md) system to map `Product` objects to `ProductEto` objects. So, you need to configure the mapping. You can check the object to object mapping document for all options, but the following example shows how to configure it with the [AutoMapper](https://automapper.org/) library.
**Example: Configure `Product` to `ProductEto` mapping using the AutoMapper**
````csharp
using System;
using AutoMapper;
using Volo.Abp.Domain.Entities.Events.Distributed;
namespace AbpDemo
{
[AutoMap(typeof(Product))]
public class ProductEto : EntityEto
{
public Guid Id { get; set; }
public string Name { get; set; }
}
}
````
This example uses the `AutoMap` attribute of the AutoMapper to configure the mapping. You could create a profile class instead. Please refer to the AutoMapper document for more options.

3
docs/en/RabbitMq.md

@ -0,0 +1,3 @@
# RabbitMQ
TODO!

8
docs/en/UI/Angular/Permission-Management.md

@ -8,7 +8,7 @@ You can get permission as boolean value from store:
```js
import { Store } from '@ngxs/store';
import { ConfigState } from '../states';
import { ConfigState } from '@abp/ng.core';
export class YourComponent {
constructor(private store: Store) {}
@ -24,7 +24,7 @@ export class YourComponent {
Or you can get it via `ConfigStateService`:
```js
import { ConfigStateService } from '../services/config-state.service';
import { ConfigStateService } from '@abp/ng.core';
export class YourComponent {
constructor(private configStateService: ConfigStateService) {}
@ -42,7 +42,7 @@ export class YourComponent {
You can use the `PermissionDirective` to manage visibility of a DOM Element accordingly to user's permission.
```html
<div *abpPermission="AbpIdentity.Roles">
<div *abpPermission="'AbpIdentity.Roles'">
This content is only visible if the user has 'AbpIdentity.Roles' permission.
</div>
```
@ -58,6 +58,8 @@ You can use `PermissionGuard` if you want to control authenticated user's permis
Add `requiredPolicy` to the `routes` property in your routing module.
```js
import { PermissionGuard } from '@abp/ng.core';
// ...
const routes: Routes = [
{
path: 'path',

1
framework/src/Volo.Abp.AspNetCore.Mvc.UI.Packages/Volo/Abp/AspNetCore/Mvc/UI/Packages/Select2/Select2ScriptContributor.cs

@ -12,6 +12,7 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Packages.Select2
{
//TODO: Add select2.full.min.js or localize!
context.Files.AddIfNotContains("/libs/select2/js/select2.min.js");
context.Files.AddIfNotContains("/libs/select2/js/select2-bootstrap-modal-patch.js");
}
}
}

2
framework/src/Volo.Abp.BlobStoring/Volo/Abp/BlobStoring/DefaultContainer.cs

@ -3,6 +3,6 @@
[BlobContainerName(Name)]
public class DefaultContainer
{
public const string Name = "Default";
public const string Name = "default";
}
}

15
framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/Events/Distributed/AbpDistributedEntityEventOptions.cs

@ -0,0 +1,15 @@
namespace Volo.Abp.Domain.Entities.Events.Distributed
{
public class AbpDistributedEntityEventOptions
{
public IAutoEntityDistributedEventSelectorList AutoEventSelectors { get; }
public EtoMappingDictionary EtoMappings { get; set; }
public AbpDistributedEntityEventOptions()
{
AutoEventSelectors = new AutoEntityDistributedEventSelectorList();
EtoMappings = new EtoMappingDictionary();
}
}
}

9
framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/Events/Distributed/AutoEntityDistributedEventSelectorList.cs

@ -0,0 +1,9 @@
using System.Collections.Generic;
namespace Volo.Abp.Domain.Entities.Events.Distributed
{
public class AutoEntityDistributedEventSelectorList : List<NamedTypeSelector>, IAutoEntityDistributedEventSelectorList
{
}
}

117
framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/Events/Distributed/AutoEntityDistributedEventSelectorListExtensions.cs

@ -0,0 +1,117 @@
using System;
using System.Collections.Generic;
using System.Linq;
using JetBrains.Annotations;
namespace Volo.Abp.Domain.Entities.Events.Distributed
{
public static class AutoEntityDistributedEventSelectorListExtensions
{
public const string AllEntitiesSelectorName = "All";
public static void AddNamespace([NotNull] this IAutoEntityDistributedEventSelectorList selectors, [NotNull] string namespaceName)
{
Check.NotNull(selectors, nameof(selectors));
var selectorName = "Namespace:" + namespaceName;
if (selectors.Any(s => s.Name == selectorName))
{
return;
}
selectors.Add(
new NamedTypeSelector(
selectorName,
t => t.FullName?.StartsWith(namespaceName) ?? false
)
);
}
/// <summary>
/// Adds a specific entity type and the types derived from that entity type.
/// </summary>
/// <typeparam name="TEntity">Type of the entity</typeparam>
public static void Add<TEntity>([NotNull] this IAutoEntityDistributedEventSelectorList selectors)
where TEntity : IEntity
{
Check.NotNull(selectors, nameof(selectors));
var selectorName = "Entity:" + typeof(TEntity).FullName;
if (selectors.Any(s => s.Name == selectorName))
{
return;
}
selectors.Add(
new NamedTypeSelector(
selectorName,
t => typeof(TEntity).IsAssignableFrom(t)
)
);
}
/// <summary>
/// Adds all entity types.
/// </summary>
public static void AddAll([NotNull] this IAutoEntityDistributedEventSelectorList selectors)
{
Check.NotNull(selectors, nameof(selectors));
if (selectors.Any(s => s.Name == AllEntitiesSelectorName))
{
return;
}
selectors.Add(
new NamedTypeSelector(
AllEntitiesSelectorName,
t => typeof(IEntity).IsAssignableFrom(t)
)
);
}
public static void Add(
[NotNull] this IAutoEntityDistributedEventSelectorList selectors,
string selectorName,
Func<Type, bool> predicate)
{
Check.NotNull(selectors, nameof(selectors));
if (selectors.Any(s => s.Name == selectorName))
{
throw new AbpException($"There is already a selector added before with the same name: {selectorName}");
}
selectors.Add(
new NamedTypeSelector(
selectorName,
predicate
)
);
}
public static void Add(
[NotNull] this IAutoEntityDistributedEventSelectorList selectors,
Func<Type, bool> predicate)
{
selectors.Add(Guid.NewGuid().ToString("N"), predicate);
}
public static bool RemoveByName(
[NotNull] this IAutoEntityDistributedEventSelectorList selectors,
[NotNull] string name)
{
Check.NotNull(selectors, nameof(selectors));
Check.NotNull(name, nameof(name));
return selectors.RemoveAll(s => s.Name == name).Count > 0;
}
public static bool IsMatch([NotNull] this IAutoEntityDistributedEventSelectorList selectors, Type entityType)
{
Check.NotNull(selectors, nameof(selectors));
return selectors.Any(s => s.Predicate(entityType));
}
}
}

6
framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/Events/Distributed/EntityToEtoMapper.cs

@ -3,7 +3,6 @@ using System.Collections.Generic;
using Microsoft.Extensions.DependencyInjection;
using Volo.Abp.DependencyInjection;
using Volo.Abp.DynamicProxy;
using Volo.Abp.EventBus.Distributed;
using Volo.Abp.ObjectMapping;
namespace Volo.Abp.Domain.Entities.Events.Distributed
@ -11,10 +10,11 @@ namespace Volo.Abp.Domain.Entities.Events.Distributed
public class EntityToEtoMapper : IEntityToEtoMapper, ITransientDependency
{
protected IHybridServiceScopeFactory HybridServiceScopeFactory { get; }
protected AbpDistributedEventBusOptions Options { get; }
protected AbpDistributedEntityEventOptions Options { get; }
public EntityToEtoMapper(
IOptions<AbpDistributedEventBusOptions> options,
IOptions<AbpDistributedEntityEventOptions> options,
IHybridServiceScopeFactory hybridServiceScopeFactory)
{
HybridServiceScopeFactory = hybridServiceScopeFactory;

3
framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/Distributed/EtoMappingDictionary.cs → framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/Events/Distributed/EtoMappingDictionary.cs

@ -1,7 +1,8 @@
using System;
using System.Collections.Generic;
using Volo.Abp.EventBus.Distributed;
namespace Volo.Abp.EventBus.Distributed
namespace Volo.Abp.Domain.Entities.Events.Distributed
{
public class EtoMappingDictionary : Dictionary<Type, EtoMappingDictionaryItem>
{

2
framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/Distributed/EtoMappingDictionaryItem.cs → framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/Events/Distributed/EtoMappingDictionaryItem.cs

@ -1,6 +1,6 @@
using System;
namespace Volo.Abp.EventBus.Distributed
namespace Volo.Abp.Domain.Entities.Events.Distributed
{
public class EtoMappingDictionaryItem
{

9
framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/Events/Distributed/IAutoEntityDistributedEventSelectorList.cs

@ -0,0 +1,9 @@
using System;
using System.Collections.Generic;
namespace Volo.Abp.Domain.Entities.Events.Distributed
{
public interface IAutoEntityDistributedEventSelectorList : IList<NamedTypeSelector>
{
}
}

74
framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/Events/EntityChangeEventHelper.cs

@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.Extensions.Options;
using Volo.Abp.Auditing;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Domain.Entities.Events.Distributed;
@ -22,13 +23,16 @@ namespace Volo.Abp.Domain.Entities.Events
protected IUnitOfWorkManager UnitOfWorkManager { get; }
protected IEntityToEtoMapper EntityToEtoMapper { get; }
protected AbpDistributedEntityEventOptions DistributedEntityEventOptions { get; }
public EntityChangeEventHelper(
IUnitOfWorkManager unitOfWorkManager,
IEntityToEtoMapper entityToEtoMapper)
IEntityToEtoMapper entityToEtoMapper,
IOptions<AbpDistributedEntityEventOptions> distributedEntityEventOptions)
{
UnitOfWorkManager = unitOfWorkManager;
EntityToEtoMapper = entityToEtoMapper;
DistributedEntityEventOptions = distributedEntityEventOptions.Value;
LocalEventBus = NullLocalEventBus.Instance;
DistributedEventBus = NullDistributedEventBus.Instance;
@ -65,18 +69,32 @@ namespace Volo.Abp.Domain.Entities.Events
false
);
var eto = EntityToEtoMapper.Map(entity);
if (eto != null)
if (ShouldPublishDistributedEventForEntity(entity))
{
await TriggerEventWithEntity(
DistributedEventBus,
typeof(EntityCreatedEto<>),
eto,
false
);
var eto = EntityToEtoMapper.Map(entity);
if (eto != null)
{
await TriggerEventWithEntity(
DistributedEventBus,
typeof(EntityCreatedEto<>),
eto,
false
);
}
}
}
private bool ShouldPublishDistributedEventForEntity(object entity)
{
return DistributedEntityEventOptions
.AutoEventSelectors
.IsMatch(
ProxyHelper
.UnProxy(entity)
.GetType()
);
}
public virtual async Task TriggerEntityUpdatingEventAsync(object entity)
{
await TriggerEventWithEntity(
@ -96,15 +114,18 @@ namespace Volo.Abp.Domain.Entities.Events
false
);
var eto = EntityToEtoMapper.Map(entity);
if (eto != null)
if (ShouldPublishDistributedEventForEntity(entity))
{
await TriggerEventWithEntity(
DistributedEventBus,
typeof(EntityUpdatedEto<>),
eto,
false
);
var eto = EntityToEtoMapper.Map(entity);
if (eto != null)
{
await TriggerEventWithEntity(
DistributedEventBus,
typeof(EntityUpdatedEto<>),
eto,
false
);
}
}
}
@ -127,15 +148,18 @@ namespace Volo.Abp.Domain.Entities.Events
false
);
var eto = EntityToEtoMapper.Map(entity);
if (eto != null)
if (ShouldPublishDistributedEventForEntity(entity))
{
await TriggerEventWithEntity(
DistributedEventBus,
typeof(EntityDeletedEto<>),
EntityToEtoMapper.Map(entity),
false
);
var eto = EntityToEtoMapper.Map(entity);
if (eto != null)
{
await TriggerEventWithEntity(
DistributedEventBus,
typeof(EntityDeletedEto<>),
eto,
false
);
}
}
}

2
framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/Distributed/AbpDistributedEventBusOptions.cs

@ -5,12 +5,10 @@ namespace Volo.Abp.EventBus.Distributed
public class AbpDistributedEventBusOptions
{
public ITypeList<IEventHandler> Handlers { get; }
public EtoMappingDictionary EtoMappings { get; set; }
public AbpDistributedEventBusOptions()
{
Handlers = new TypeList<IEventHandler>();
EtoMappings = new EtoMappingDictionary();
}
}
}

7
framework/src/Volo.Abp.Localization/Volo/Abp/Localization/Resources/AbpLocalization/tr.json

@ -0,0 +1,7 @@
{
"culture": "tr",
"texts": {
"DisplayName:Abp.Localization.DefaultLanguage": "Varsayılan dil",
"Description:Abp.Localization.DefaultLanguage": "Varsayılan uygulama dili."
}
}

22
framework/test/Volo.Abp.Ddd.Tests/Volo/Abp/Domain/Entities/Events/Distributed/AutoEntityDistributedEventSelectorListExtensions_Tests.cs

@ -0,0 +1,22 @@
using Shouldly;
using Xunit;
namespace Volo.Abp.Domain.Entities.Events.Distributed
{
public class AutoEntityDistributedEventSelectorListExtensions_Tests
{
[Fact]
public void Add_Entity()
{
var selectors = new AutoEntityDistributedEventSelectorList();
selectors.Add<MyEntity>();
selectors.IsMatch(typeof(MyEntity)).ShouldBeTrue();
}
private class MyEntity : Entity<string>
{
}
}
}

6
framework/test/Volo.Abp.Emailing.Tests/Volo/Abp/Emailing/Localization/tr.json

@ -0,0 +1,6 @@
{
"culture": "tr",
"texts": {
"hello": "Merhaba"
}
}

5
framework/test/Volo.Abp.Localization.Tests/Volo/Abp/Localization/TestResources/Base/CountryNames/tr.json

@ -1,6 +1,7 @@
{
{
"culture": "tr",
"texts": {
"USA": "Amerika Birleşik Devletleri"
"USA": "Amerika Birleşik Devletleri",
"Brazil": "Brezilya"
}
}

7
framework/test/Volo.Abp.Localization.Tests/Volo/Abp/Localization/TestResources/Base/Validation/tr.json

@ -0,0 +1,7 @@
{
"culture": "tr",
"texts": {
"ThisFieldIsRequired": "Bu alan zorunludur",
"MaxLenghtErrorMessage": "Bu alan maksimum '{0}' karakter olabilir"
}
}

6
framework/test/Volo.Abp.Localization.Tests/Volo/Abp/Localization/TestResources/Source/tr.json

@ -1,9 +1,11 @@
{
{
"culture": "tr",
"texts": {
"Hello <b>{0}</b>.": "Merhaba <b>{0}</b>.",
"Car": "Araba",
"CarPlural": "Araba",
"Universe": "Evren"
"MaxLenghtErrorMessage": "Bu alanın uzunluğu maksimum '{0}' karakter olabilir",
"Universe": "Evren",
"FortyTwo": "Kırk İki"
}
}

6
framework/test/Volo.Abp.Localization.Tests/Volo/Abp/Localization/TestResources/SourceExt/tr.json

@ -0,0 +1,6 @@
{
"culture": "tr",
"texts": {
"SeeYou": "Görüşürüz"
}
}

5
framework/test/Volo.Abp.TestApp/Volo/Abp/TestApp/TestAppModule.cs

@ -4,7 +4,7 @@ using Volo.Abp.Autofac;
using Volo.Abp.Modularity;
using Volo.Abp.TestApp.Domain;
using Volo.Abp.AutoMapper;
using Volo.Abp.EventBus.Distributed;
using Volo.Abp.Domain.Entities.Events.Distributed;
using Volo.Abp.TestApp.Application.Dto;
using Volo.Abp.Threading;
@ -45,8 +45,9 @@ namespace Volo.Abp.TestApp
private void ConfigureDistributedEventBus()
{
Configure<AbpDistributedEventBusOptions>(options =>
Configure<AbpDistributedEntityEventOptions>(options =>
{
options.AutoEventSelectors.Add<Person>();
options.EtoMappings.Add<Person, PersonEto>();
});
}

10
modules/account/src/Volo.Abp.Account.Application.Contracts/Volo/Abp/Account/Localization/Resources/tr.json

@ -1,4 +1,4 @@
{
{
"culture": "tr",
"texts": {
"UserName": "Kullanıcı adı",
@ -11,10 +11,12 @@
"InvalidUserNameOrPassword": "Kullanıcı adı ya da şifre geçersiz!",
"LoginIsNotAllowed": "Giriş yapamazsınız! E-posta adresinizi ya da telefon numaranızı doğrulamanız gerekiyor.",
"SelfRegistrationDisabledMessage": "Bu uygulama için kullanıcıların kendi kendilerine kaydolmaları engellenmiştir. Yeni bir kullanıcı kaydetmek için lütfen uygulama yöneticisi ile iletişime geçin.",
"LocalLoginDisabledMessage": "Bu uygulama için local login devre dışı bırakılmıştır.",
"Login": "Giriş yap",
"Cancel": "İptal",
"Register": "Kayıt ol",
"AreYouANewUser": "Yeni bir kullanıcı mısınız?",
"AlreadyRegistered": "Zaten kayıtlı mı?",
"InvalidLoginRequest": "Başarısız giriş isteği",
"ThereAreNoLoginSchemesConfiguredForThisClient": "Bu client için konfigüre edilmiş giriş şeması bulunamadı.",
"LogInUsingYourProviderAccount": "{0} hesabınızla giriş yapın.",
@ -34,6 +36,10 @@
"PasswordChanged": "Şifre değiştirildi",
"NewPasswordConfirmFailed": "Lütfen yeni şifreyi onaylayın.",
"Manage": "Manage",
"ManageYourProfile": "Profilinizi yönetin"
"ManageYourProfile": "Profilinizi yönetin",
"DisplayName:Abp.Account.IsSelfRegistrationEnabled": "self-registration etkin mi ?",
"Description:Abp.Account.IsSelfRegistrationEnabled": "Bir kullanıcının hesabı kendisi tarafından kaydedip kaydedememesidir.",
"DisplayName:Abp.Account.EnableLocalLogin": "Yerel bir hesapla kimlik doğrulaması",
"Description:Abp.Account.EnableLocalLogin": "Sunucunun, kullanıcıların yerel bir hesapla kimlik doğrulamasına izin verip vermeyeceğini belirtir."
}
}

7
modules/blogging/src/Volo.Blogging.Domain.Shared/Volo/Blogging/Localization/Resources/tr.json

@ -1,4 +1,4 @@
{
{
"culture": "tr",
"texts": {
"Menu:Blogs": "Bloglar",
@ -20,7 +20,6 @@
"SeeAll": "Hepsini Gör",
"PopularTags": "Popüler Etiketler",
"WiewsWithCount": "{0} görüntüleme",
"ShareOnTwitter": "Twitter'da paylaş",
"LastPosts": "Son Yazılar",
"LeaveComment": "Yorum Bırak",
"TagsInThisArticle": "Makalenin Etiketleri",
@ -33,6 +32,7 @@
"AreYouSure": "Emin misiniz?",
"CommentWithCount": "{0} yorum",
"Comment": "Yorum",
"ShareOnTwitter": "Twitter'da paylaş",
"CoverImage": "Kapak resmi",
"CreateANewPost": "Yeni Yazı oluştur",
"CreateANewBlog": "Yeni Blog Ekle",
@ -43,6 +43,7 @@
"Description": "Açıklama",
"Blogs": "Bloglar",
"Tags": "Etiketler",
"ShareOn": "Paylaş"
"ShareOn": "Paylaş",
"TitleLengthWarning": "Başlığınınz SEO dostu olabilmesi için 60 karakterden az olmasını sağlayın!"
}
}

4
modules/blogging/src/Volo.Blogging.Domain/Volo/Blogging/BloggingDomainModule.cs

@ -1,7 +1,7 @@
using Microsoft.Extensions.DependencyInjection;
using Volo.Abp.AutoMapper;
using Volo.Abp.Domain;
using Volo.Abp.EventBus.Distributed;
using Volo.Abp.Domain.Entities.Events.Distributed;
using Volo.Abp.Modularity;
using Volo.Blogging.Blogs;
using Volo.Blogging.Comments;
@ -25,7 +25,7 @@ namespace Volo.Blogging
options.AddProfile<BloggingDomainMappingProfile>(validate: true);
});
Configure<AbpDistributedEventBusOptions>(options =>
Configure<AbpDistributedEntityEventOptions>(options =>
{
options.EtoMappings.Add<Blog, BlogEto>(typeof(BloggingDomainModule));
options.EtoMappings.Add<Comment, CommentEto>(typeof(BloggingDomainModule));

3
modules/docs/app/VoloDocs.Web/Localization/Resources/VoloDocs/Web/tr.json

@ -1,6 +1,7 @@
{
{
"culture": "tr",
"texts": {
"DocsTitle": "VoloDocs",
"WelcomeVoloDocs": "VoloDocs Hoşgeldiniz!",
"NoProjectWarning": "Henüz bir proje yok!",
"CreateYourFirstProject": "İlk projenizi oluşturmak için tıklayın",

22
modules/docs/src/Volo.Docs.Admin.Application.Contracts/Volo/Docs/Admin/Documents/GetAllInput.cs

@ -12,10 +12,28 @@ namespace Volo.Docs.Admin.Documents
[StringLength(DocumentConsts.MaxNameLength)]
public string Name { get; set; }
[StringLength(DocumentConsts.MaxVersionNameLength)]
public string Version { get; set; }
[StringLength(DocumentConsts.MaxLanguageCodeNameLength)]
public string LanguageCode { get; set; }
[StringLength(DocumentConsts.MaxVersionNameLength)]
public string Version { get; set; }
[StringLength(DocumentConsts.MaxFileNameNameLength)]
public string FileName { get; set; }
[StringLength(DocumentConsts.MaxFormatNameLength)]
public string Format { get; set; }
public DateTime? CreationTimeMin { get; set; }
public DateTime? CreationTimeMax { get; set; }
public DateTime? LastUpdatedTimeMin { get; set; }
public DateTime? LastUpdatedTimeMax { get; set; }
public DateTime? LastSignificantUpdateTimeMin { get; set; }
public DateTime? LastSignificantUpdateTimeMax { get; set; }
public DateTime? LastCachedTimeMin { get; set; }
public DateTime? LastCachedTimeMax { get; set; }
}
}

12
modules/docs/src/Volo.Docs.Admin.Application.Contracts/Volo/Docs/Admin/Localization/Resources/Docs/ApplicationContracts/en.json

@ -43,6 +43,16 @@
"ReIndexDocumentConfirmation": "Are you sure you want to reindex this item?",
"DeleteDocumentFromDbConfirmation": "Are you sure you want to delete this item from database?",
"DeleteFromDatabase": "Delete from database",
"Deleted": "Deleted"
"Deleted": "Deleted",
"Search": "Search",
"StartDate": "Start date",
"EndDate": "End date",
"CreationTime": "Creation time",
"LastUpdateTime": "Last update",
"LastSignificantUpdateTime": "Last significant update",
"Version": "Version",
"LanguageCode": "Language code",
"FileName": "File name",
"LastCachedTime": "Cache time"
}
}

16
modules/docs/src/Volo.Docs.Admin.Application.Contracts/Volo/Docs/Admin/Localization/Resources/Docs/ApplicationContracts/tr.json

@ -1,4 +1,4 @@
{
{
"culture": "tr",
"texts": {
"Permission:DocumentManagement": "Döküman yönetimi",
@ -7,6 +7,7 @@
"Permission:Delete": "Sil",
"Permission:Create": "Oluştur",
"Permission:Documents": "Döküman",
"Menu:Documents": "Dokümanlar",
"Menu:DocumentManagement": "Dökümanlar",
"Menu:ProjectManagement": "Projeler",
"CreateANewProject": "Yeni proje oluştur",
@ -29,8 +30,19 @@
"DisplayName:LatestVersionBranchName": "Son versiyon Branch adı",
"DisplayName:GitHubRootUrl": "GitHub kök adresi",
"DisplayName:GitHubAccessToken": "GitHub erişim token",
"DisplayName:GitHubUserAgent": "GitHub kullanıcı temsilcisi",
"DisplayName:All": "Çekme bütün",
"DisplayName:LanguageCode": "Dil kodu",
"DisplayName:Version": "versiyon"
"DisplayName:Version": "versiyon",
"Documents": "Dokümanlar",
"RemoveFromCache": "Önbellekten kaldır",
"Reindex": "Yeniden İndeksle",
"ReindexCompleted": "Yeniden indeksleme tamamlandı",
"RemovedFromCache": "Önbellekten kaldırıldı",
"RemoveFromCacheConfirmation": "Bu maddeyi önbellekten kaldırmak istediğiniz emin misiniz?",
"ReIndexDocumentConfirmation": "Bu maddeyi yeniden indekslemek istediğinize emin misiniz?",
"DeleteDocumentFromDbConfirmation": "Bu maddeyi veritabanından silmek istediğinize emin misiniz?",
"DeleteFromDatabase": "Veritabanından sil",
"Deleted": "Silindi"
}
}

36
modules/docs/src/Volo.Docs.Admin.Application/Volo/Docs/Admin/Documents/DocumentAdminAppService.cs

@ -137,20 +137,40 @@ namespace Volo.Docs.Admin.Documents
public async Task<PagedResultDto<DocumentDto>> GetAllAsync(GetAllInput input)
{
var totalCount = await _documentRepository.GetAllCountAsync(
projectId: input.ProjectId,
name: input.Name,
version: input.Version,
languageCode: input.LanguageCode,
sorting: input.Sorting,
maxResultCount: input.MaxResultCount,
skipCount: input.SkipCount
);
projectId: input.ProjectId,
name: input.Name,
version: input.Version,
languageCode: input.LanguageCode,
fileName: input.FileName,
format: input.Format,
creationTimeMin: input.CreationTimeMin,
creationTimeMax: input.CreationTimeMax,
lastUpdatedTimeMin: input.LastUpdatedTimeMin,
lastUpdatedTimeMax: input.LastUpdatedTimeMax,
lastSignificantUpdateTimeMin: input.LastSignificantUpdateTimeMin,
lastSignificantUpdateTimeMax: input.LastSignificantUpdateTimeMax,
lastCachedTimeMin: input.LastCachedTimeMin,
lastCachedTimeMax: input.LastCachedTimeMax,
sorting: input.Sorting,
maxResultCount: input.MaxResultCount,
skipCount: input.SkipCount
);
var docs = await _documentRepository.GetAllAsync(
projectId: input.ProjectId,
name: input.Name,
version: input.Version,
languageCode: input.LanguageCode,
fileName: input.FileName,
format: input.Format,
creationTimeMin: input.CreationTimeMin,
creationTimeMax: input.CreationTimeMax,
lastUpdatedTimeMin: input.LastUpdatedTimeMin,
lastUpdatedTimeMax: input.LastUpdatedTimeMax,
lastSignificantUpdateTimeMin: input.LastSignificantUpdateTimeMin,
lastSignificantUpdateTimeMax: input.LastSignificantUpdateTimeMax,
lastCachedTimeMin: input.LastCachedTimeMin,
lastCachedTimeMax: input.LastCachedTimeMax,
sorting: input.Sorting,
maxResultCount: input.MaxResultCount,
skipCount: input.SkipCount

219
modules/docs/src/Volo.Docs.Admin.Web/Pages/Docs/Admin/Documents/Index.cshtml

@ -22,31 +22,194 @@
<abp-script src="/Pages/Docs/Admin/Documents/index.js" />
}
<abp-card>
<abp-card-header>
<abp-row>
<h2>Filters ...</h2>
@*<abp-column size-md="_6" class="text-right">
<abp-button button-type="Primary" icon="plus" text="@L["ReIndexAllProjects"].Value" id="ReIndexAllProjects" />
</abp-column>*@
</abp-row>
</abp-card-header>
<abp-card-body>
<abp-table striped-rows="true" id="DocumentsTable" class="nowrap">
<thead>
<tr>
<th>@L["Actions"]</th>
<th>@L["Name"]</th>
<th>@L["Version"]</th>
<th>@L["LanguageCode"]</th>
<th>@L["FileName"]</th>
<th>@L["Format"]</th>
<th>@L["CreationTime"]</th>
<th>@L["LastUpdatedTime"]</th>
<th>@L["LastSignificantUpdateTime"]</th>
<th>@L["LastCachedTime"]</th>
</tr>
</thead>
</abp-table>
</abp-card-body>
</abp-card>
@section styles {
<abp-style src="/Pages/Docs/Admin/Documents/index.min.css" />
}
<div id="DocumentsContainer">
<abp-card>
<abp-card-header>
<form class="form-inline" autocomplete="off" id="FilterForm">
<div class="form-row">
<div class="col-auto">
<div class="input-group mb-2">
<div class="input-group-prepend">
<div class="input-group-text">@L["Name"].Value</div>
</div>
<input type="text"
id="Name"
name="Name"
class="form-control mr-sm-2">
</div>
</div>
<div class="col-auto">
<div class="input-group mb-2">
<div class="input-group-prepend">
<div class="input-group-text">@L["Version"].Value</div>
</div>
<input type="text"
id="Version"
name="Version"
class="form-control mr-sm-2">
</div>
</div>
<div class="col-auto">
<div class="input-group mb-2">
<div class="input-group-prepend">
<div class="input-group-text">@L["LanguageCode"].Value</div>
</div>
<input type="text"
id="LanguageCode"
name="LanguageCode"
class="form-control mr-sm-2">
</div>
</div>
<div class="col-auto">
<div class="input-group mb-2">
<div class="input-group-prepend">
<div class="input-group-text">@L["FileName"].Value</div>
</div>
<input type="text"
id="FileName"
name="FileName"
class="form-control mr-sm-2">
</div>
</div>
<div class="col-auto">
<div class="input-group mb-2">
<div class="input-group-prepend">
<div class="input-group-text">@L["Format"].Value</div>
</div>
<input type="text"
id="Format"
name="Format"
class="form-control mr-sm-2">
</div>
</div>
<div class="col-auto">
<div class="input-group mb-2">
<div class="input-group-prepend">
<div class="input-group-text">@L["CreationTime"].Value</div>
</div>
<span>
<input type="date"
id="CreationTimeMin"
name="CreationTimeMin"
class="form-control datepicker"
placeholder="@L["StartDate"]">
<span>-</span>
<input type="date"
id="CreationTimeMax"
name="CreationTimeMax"
placeholder="@L["EndDate"]"
class="form-control datepicker">
</span>
</div>
</div>
<div class="col-auto">
<div class="input-group mb-2">
<div class="input-group-prepend">
<div class="input-group-text">@L["LastUpdateTime"].Value</div>
</div>
<span>
<input type="date"
id="LastUpdatedTimeMin"
name="LastUpdatedTimeMin"
class="form-control datepicker"
placeholder="@L["StartDate"]">
<span>-</span>
<input type="date"
id="LastUpdatedTimeMax"
name="LastUpdatedTimeMax"
placeholder="@L["EndDate"]"
class="form-control datepicker">
</span>
</div>
</div>
<div class="col-auto">
<div class="input-group mb-2">
<div class="input-group-prepend">
<div class="input-group-text">@L["LastSignificantUpdateTime"].Value</div>
</div>
<span>
<input type="date"
id="LastSignificantUpdateTimeMin"
name="LastSignificantUpdateTimeMin"
class="form-control datepicker"
placeholder="@L["StartDate"]">
<span>-</span>
<input type="date"
id="LastSignificantUpdateTimeMax"
name="LastSignificantUpdateTimeMax"
placeholder="@L["EndDate"]"
class="form-control datepicker">
</span>
</div>
</div>
<div class="col-auto">
<div class="input-group mb-2">
<div class="input-group-prepend">
<div class="input-group-text">@L["LastCachedTime"].Value</div>
</div>
<span>
<input type="date"
id="LastCachedTimeMin"
name="LastCachedTimeMin"
class="form-control datepicker"
placeholder="@L["StartDate"]">
<span>-</span>
<input type="date"
id="LastCachedTimeMax"
name="LastCachedTimeMax"
placeholder="@L["EndDate"]"
class="form-control datepicker">
</span>
</div>
</div>
<div class="col-auto">
<abp-button button-type="Primary" icon="search" id="SearchButton" style="line-height: 25px;" text="@L["Search"].Value"></abp-button>
</div>
</div>
</form>
</abp-card-header>
<abp-card-body>
<abp-table striped-rows="true" id="DocumentsTable" class="nowrap">
<thead>
<tr>
<th>@L["Actions"]</th>
<th>@L["Name"]</th>
<th>@L["Version"]</th>
<th>@L["LanguageCode"]</th>
<th>@L["FileName"]</th>
<th>@L["Format"]</th>
<th>@L["CreationTime"]</th>
<th>@L["LastUpdatedTime"]</th>
<th>@L["LastSignificantUpdateTime"]</th>
<th>@L["LastCachedTime"]</th>
</tr>
</thead>
</abp-table>
</abp-card-body>
</abp-card>
</div>

3
modules/docs/src/Volo.Docs.Admin.Web/Pages/Docs/Admin/Documents/Index.cshtml.cs

@ -1,6 +1,9 @@
using System;
using System.ComponentModel.DataAnnotations;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Volo.Docs.Documents;
namespace Volo.Docs.Admin.Pages.Docs.Admin.Documents
{

3
modules/docs/src/Volo.Docs.Admin.Web/Pages/Docs/Admin/Documents/index.css

@ -0,0 +1,3 @@
#DocumentsContainer .datepicker {
display: inline-block !important;
width: 7rem !important; }

71
modules/docs/src/Volo.Docs.Admin.Web/Pages/Docs/Admin/Documents/index.js

@ -1,8 +1,32 @@
$(function () {
var l = abp.localization.getResource('Docs');
var service = window.volo.docs.admin.documentsAdmin;
var _dataTable = $('#DocumentsTable').DataTable(abp.libs.datatables.normalizeConfiguration({
var getFormattedDate = function ($datePicker) {
return $datePicker.data().datepicker.getFormattedDate("yyyy-mm-dd");
};
var getFilter = function () {
return {
projectId: $("#ProjectId").val(),
name: $("#Name").val(),
version: $("#Version").val(),
languageCode: $("#LanguageCode").val(),
fileName: $("#FileName").val(),
format: $("#Format").val(),
creationTimeMin: getFormattedDate($("#CreationTimeMin")),
creationTimeMax: getFormattedDate($("#CreationTimeMax")),
lastUpdatedTimeMin: getFormattedDate($("#LastUpdatedTimeMin")),
lastUpdatedTimeMax: getFormattedDate($("#LastUpdatedTimeMax")),
lastSignificantUpdateTimeMin: getFormattedDate($("#LastSignificantUpdateTimeMin")),
lastSignificantUpdateTimeMax: getFormattedDate($("#LastSignificantUpdateTimeMax")),
lastCachedTimeMin: getFormattedDate($("#LastCachedTimeMin")),
lastCachedTimeMax: getFormattedDate($("#LastCachedTimeMax"))
};
};
var dataTable = $('#DocumentsTable').DataTable(abp.libs.datatables.normalizeConfiguration({
processing: true,
serverSide: true,
scrollX: true,
@ -10,7 +34,7 @@
searching: false,
autoWidth: false,
scrollCollapse: true,
ajax: abp.libs.datatables.createAjax(volo.docs.admin.documentsAdmin.getAll),
ajax: abp.libs.datatables.createAjax(service.getAll, getFilter),
columnDefs: [
{
rowAction: {
@ -21,11 +45,10 @@
visible: abp.auth.isGranted('Docs.Admin.Documents'),
confirmMessage: function (data) { return l('RemoveFromCacheConfirmation'); },
action: function (data) {
volo.docs.admin.documentsAdmin
.removeFromCache(data.record.id)
service.removeFromCache(data.record.id)
.then(function () {
abp.message.success(l('RemovedFromCache'));
_dataTable.ajax.reload();
dataTable.ajax.reload();
});
}
},
@ -34,11 +57,10 @@
visible: abp.auth.isGranted('Docs.Admin.Documents'),
confirmMessage: function (data) { return l('ReIndexDocumentConfirmation'); },
action: function (data) {
volo.docs.admin.documentsAdmin
.reindex(data.record.id)
service.reindex(data.record.id)
.then(function () {
abp.message.success(l('ReindexCompleted'));
_dataTable.ajax.reload();
dataTable.ajax.reload();
});
}
},
@ -47,11 +69,10 @@
visible: abp.auth.isGranted('Docs.Admin.Documents'),
confirmMessage: function (data) { return l('DeleteDocumentFromDbConfirmation'); },
action: function (data) {
volo.docs.admin.documentsAdmin
.deleteFromDatabase(data.record.id)
service.deleteFromDatabase(data.record.id)
.then(function () {
abp.message.success(l('Deleted'));
_dataTable.ajax.reload();
dataTable.ajax.reload();
});
}
}
@ -76,14 +97,7 @@
},
{
target: 5,
data: "format",
render: function (data) {
if (data === 'md') {
return 'markdown';
}
return data;
}
data: "format"
},
{
target: 6,
@ -136,18 +150,15 @@
]
}));
$("#FilterForm input[type='text']").keypress(function (e) {
if (e.which === 13) {
dataTable.ajax.reload();
}
});
$("#ReIndexAllProjects").click(function (event) {
abp.message.confirm(l('ReIndexAllProjectConfirmationMessage'))
.done(function (accepted) {
if (accepted) {
volo.docs.admin.projectsAdmin
.reindexAll()
.then(function () {
abp.message.success(l('SuccessfullyReIndexAllProject'));
});
}
});
$("#SearchButton").click(function (e) {
e.preventDefault();
dataTable.ajax.reload();
});
});

1
modules/docs/src/Volo.Docs.Admin.Web/Pages/Docs/Admin/Documents/index.min.css

@ -0,0 +1 @@
#DocumentsContainer .datepicker{display:inline-block !important;width:7rem !important;}

6
modules/docs/src/Volo.Docs.Admin.Web/Pages/Docs/Admin/Documents/index.scss

@ -0,0 +1,6 @@
#DocumentsContainer {
.datepicker {
display: inline-block !important;
width: 7rem !important;
}
}

8
modules/docs/src/Volo.Docs.Admin.Web/Volo.Docs.Admin.Web.csproj

@ -13,13 +13,16 @@
<TypeScriptToolsVersion>2.8</TypeScriptToolsVersion>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="CommonMark.NET" Version="0.15.1" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\..\framework\src\Volo.Abp.AutoMapper\Volo.Abp.AutoMapper.csproj" />
<ProjectReference Include="..\..\..\..\framework\src\Volo.Abp.AspNetCore.Mvc.UI.Bundling\Volo.Abp.AspNetCore.Mvc.UI.Bundling.csproj" />
<ProjectReference Include="..\..\..\..\framework\src\Volo.Abp.AspNetCore.Mvc.UI.Bootstrap\Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.csproj" />
<ProjectReference Include="..\..\..\..\framework\src\Volo.Abp.AspNetCore.Mvc.UI.Packages\Volo.Abp.AspNetCore.Mvc.UI.Packages.csproj" />
<ProjectReference Include="..\Volo.Docs.Admin.HttpApi\Volo.Docs.Admin.HttpApi.csproj" />
<PackageReference Include="CommonMark.NET" Version="0.15.1" />
</ItemGroup>
<ItemGroup>
@ -29,8 +32,7 @@
<Content Remove="Pages\**\*.js" />
<Content Remove="Properties\launchSettings.json" />
<Content Remove="compilerconfig.json" />
<Content Remove="compilerconfig.json.defaults" />
<None Remove="Pages\Docs\Admin\Documents\index.js" />
<Content Remove="compilerconfig.json.defaults" />
<None Include="compilerconfig.json" />
<None Include="Properties\launchSettings.json" />
</ItemGroup>

6
modules/docs/src/Volo.Docs.Admin.Web/compilerconfig.json

@ -0,0 +1,6 @@
[
{
"outputFile": "Pages/Docs/Admin/Documents/index.css",
"inputFile": "Pages/Docs/Admin/Documents/index.scss"
}
]

63
modules/docs/src/Volo.Docs.Admin.Web/compilerconfig.json.defaults

@ -0,0 +1,63 @@
{
"compilers": {
"less": {
"autoPrefix": "",
"cssComb": "none",
"ieCompat": true,
"strictMath": false,
"strictUnits": false,
"relativeUrls": true,
"rootPath": "",
"sourceMapRoot": "",
"sourceMapBasePath": "",
"sourceMap": false
},
"sass": {
"autoPrefix": "",
"includePath": "",
"indentType": "space",
"indentWidth": 2,
"outputStyle": "nested",
"Precision": 5,
"relativeUrls": true,
"sourceMapRoot": "",
"lineFeed": "",
"sourceMap": false
},
"stylus": {
"sourceMap": false
},
"babel": {
"sourceMap": false
},
"coffeescript": {
"bare": false,
"runtimeMode": "node",
"sourceMap": false
},
"handlebars": {
"root": "",
"noBOM": false,
"name": "",
"namespace": "",
"knownHelpersOnly": false,
"forcePartial": false,
"knownHelpers": [],
"commonjs": "",
"amd": false,
"sourceMap": false
}
},
"minifiers": {
"css": {
"enabled": true,
"termSemicolons": true,
"gzip": false
},
"javascript": {
"enabled": true,
"termSemicolons": true,
"gzip": false
}
}
}

4
modules/docs/src/Volo.Docs.Domain/Volo/Docs/DocsDomainModule.cs

@ -4,7 +4,7 @@ using Microsoft.Extensions.Options;
using Volo.Abp;
using Volo.Abp.AutoMapper;
using Volo.Abp.Domain;
using Volo.Abp.EventBus.Distributed;
using Volo.Abp.Domain.Entities.Events.Distributed;
using Volo.Abp.Localization;
using Volo.Abp.Modularity;
using Volo.Abp.Threading;
@ -34,7 +34,7 @@ namespace Volo.Docs
options.AddProfile<DocsDomainMappingProfile>(validate: true);
});
Configure<AbpDistributedEventBusOptions>(options =>
Configure<AbpDistributedEntityEventOptions>(options =>
{
options.EtoMappings.Add<Document, DocumentEto>(typeof(DocsDomainModule));
options.EtoMappings.Add<Project, ProjectEto>(typeof(DocsDomainModule));

23
modules/docs/src/Volo.Docs.Domain/Volo/Docs/Documents/IDocumentRepository.cs

@ -23,10 +23,21 @@ namespace Volo.Docs.Documents
string version,
CancellationToken cancellationToken = default);
Task<List<Document>> GetAllAsync(Guid? projectId,
Task<List<Document>> GetAllAsync(
Guid? projectId,
string name,
string version,
string languageCode,
string fileName,
string format,
DateTime? creationTimeMin,
DateTime? creationTimeMax,
DateTime? lastUpdatedTimeMin,
DateTime? lastUpdatedTimeMax,
DateTime? lastSignificantUpdateTimeMin,
DateTime? lastSignificantUpdateTimeMax,
DateTime? lastCachedTimeMin,
DateTime? lastCachedTimeMax,
string sorting = null,
int maxResultCount = int.MaxValue,
int skipCount = 0,
@ -37,6 +48,16 @@ namespace Volo.Docs.Documents
string name,
string version,
string languageCode,
string fileName,
string format,
DateTime? creationTimeMin,
DateTime? creationTimeMax,
DateTime? lastUpdatedTimeMin,
DateTime? lastUpdatedTimeMax,
DateTime? lastSignificantUpdateTimeMin,
DateTime? lastSignificantUpdateTimeMax,
DateTime? lastCachedTimeMin,
DateTime? lastCachedTimeMax,
string sorting = null,
int maxResultCount = int.MaxValue,
int skipCount = 0,

17
modules/docs/src/Volo.Docs.Domain/Volo/Docs/Localization/Domain/tr.json

@ -1,4 +1,4 @@
{
{
"culture": "tr",
"texts": {
"Documents": "Dökümanlar",
@ -9,17 +9,30 @@
"Edit": "Düzenle",
"LastEditTime": "Son Düzenleme",
"Delete": "Sil",
"ClearCache": "Önbelleği temizle",
"ClearCacheConfirmationMessage": "\"{0}\" Projesinin tüm önbelliğini temizlemek istediğinize emin misiniz? ",
"ReIndexAllProjects": "Tüm projeleri yeniden indexle",
"ReIndexProject": "Projeyi yeniden indeksle",
"ReIndexProjectConfirmationMessage": "\"{0}\" Projesini yeniden insdekslemek istediğinize emin misiniz?",
"SuccessfullyReIndexProject": "\"{0}\" Projesi başarıyla yeniden indekslendi",
"ReIndexAllProjectConfirmationMessage": "Tüm projeleri yeniden indekslemek istediğinize emin misiniz?",
"SuccessfullyReIndexAllProject": "Tüm projeler başarıyla yeniden indekslendi",
"InThisDocument": "Bu dökümanda",
"GoToTop": "En üste çık",
"Projects": "Proje(ler)",
"NoProjectWarning": "Hiç proje yok!",
"DocumentNotFound": "Aradığınız döküman bulunamadı!",
"ProjectNotFound": "Talep edilen proje bulunamadı!",
"NavigationDocumentNotFound": "Bu döküman için menü bulunamadı!",
"DocumentNotFoundInSelectedLanguage": "İstediğiniz dilde belge bulunamadı. Varsayılan dilde belge gösterilir.",
"FilterTopics": "Konuları Filtrele",
"FullSearch": "Dokümanlarda Ara",
"Volo.Docs.Domain:010001": "Elastic search etkin değil",
"MultipleVersionDocumentInfo": "Bu dökümanın birden çok versiyonu bulunmaktadır. Sizin için en uygun olan seçenekleri seçiniz.",
"New": "Yeni",
"Upd": "Günc",
"NewExplanation": "Son iki hafta içinde oluşturuldu.",
"UpdatedExplanation": "Son iki hafta içinde güncellendi."
"UpdatedExplanation": "Son iki hafta içinde güncellendi.",
"Volo.Docs.Domain:010002": "ShortName {ShortName} zaten var."
}
}

103
modules/docs/src/Volo.Docs.EntityFrameworkCore/Volo/Docs/Documents/EFCoreDocumentRepository.cs

@ -24,16 +24,44 @@ namespace Volo.Docs.Documents
return await DbSet.Where(d => d.ProjectId == projectId).ToListAsync(cancellationToken: cancellationToken);
}
public async Task<List<Document>> GetAllAsync(Guid? projectId,
public async Task<List<Document>> GetAllAsync(
Guid? projectId,
string name,
string version,
string languageCode,
string fileName,
string format,
DateTime? creationTimeMin,
DateTime? creationTimeMax,
DateTime? lastUpdatedTimeMin,
DateTime? lastUpdatedTimeMax,
DateTime? lastSignificantUpdateTimeMin,
DateTime? lastSignificantUpdateTimeMax,
DateTime? lastCachedTimeMin,
DateTime? lastCachedTimeMax,
string sorting = null,
int maxResultCount = int.MaxValue,
int skipCount = 0,
CancellationToken cancellationToken = default)
{
var query = ApplyFilterForGetAll(DbSet, projectId, name, version, languageCode);
var query = ApplyFilterForGetAll(
DbSet,
projectId: projectId,
name: name,
version: version,
languageCode: languageCode,
format: format,
fileName: fileName,
creationTimeMin: creationTimeMin,
creationTimeMax: creationTimeMax,
lastUpdatedTimeMin: lastUpdatedTimeMin,
lastUpdatedTimeMax: lastUpdatedTimeMax,
lastSignificantUpdateTimeMin: lastSignificantUpdateTimeMin,
lastSignificantUpdateTimeMax: lastSignificantUpdateTimeMax,
lastCachedTimeMin: lastCachedTimeMin,
lastCachedTimeMax: lastCachedTimeMax
);
query = query.OrderBy(string.IsNullOrWhiteSpace(sorting) ? nameof(Document.Name) : sorting);
return await query.PageBy(skipCount, maxResultCount).ToListAsync(cancellationToken);
}
@ -43,12 +71,39 @@ namespace Volo.Docs.Documents
string name,
string version,
string languageCode,
string fileName,
string format,
DateTime? creationTimeMin,
DateTime? creationTimeMax,
DateTime? lastUpdatedTimeMin,
DateTime? lastUpdatedTimeMax,
DateTime? lastSignificantUpdateTimeMin,
DateTime? lastSignificantUpdateTimeMax,
DateTime? lastCachedTimeMin,
DateTime? lastCachedTimeMax,
string sorting = null,
int maxResultCount = int.MaxValue,
int skipCount = 0,
CancellationToken cancellationToken = default)
{
var query = ApplyFilterForGetAll(DbSet, projectId, name, version, languageCode);
var query = ApplyFilterForGetAll(
DbSet,
projectId: projectId,
name: name,
version: version,
languageCode: languageCode,
format: format,
fileName: fileName,
creationTimeMin: creationTimeMin,
creationTimeMax: creationTimeMax,
lastUpdatedTimeMin: lastUpdatedTimeMin,
lastUpdatedTimeMax: lastUpdatedTimeMax,
lastSignificantUpdateTimeMin: lastSignificantUpdateTimeMin,
lastSignificantUpdateTimeMax: lastSignificantUpdateTimeMax,
lastCachedTimeMin: lastCachedTimeMin,
lastCachedTimeMax: lastCachedTimeMax
);
return await query.LongCountAsync(GetCancellationToken(cancellationToken));
}
@ -81,13 +136,47 @@ namespace Volo.Docs.Documents
string name,
string version,
string languageCode,
string fileName,
string format,
DateTime? creationTimeMin,
DateTime? creationTimeMax,
DateTime? lastUpdatedTimeMin,
DateTime? lastUpdatedTimeMax,
DateTime? lastSignificantUpdateTimeMin,
DateTime? lastSignificantUpdateTimeMax,
DateTime? lastCachedTimeMin,
DateTime? lastCachedTimeMax,
CancellationToken cancellationToken = default)
{
return DbSet
.WhereIf(projectId.HasValue, d => d.ProjectId == projectId.Value)
.WhereIf(name != null, d => d.Name != null && d.Name.Contains(name))
.WhereIf(version != null, d => d.Version != null && d.Version == version)
.WhereIf(languageCode != null, d => d.LanguageCode != null && d.LanguageCode == languageCode);
.WhereIf(projectId.HasValue,
d => d.ProjectId == projectId.Value)
.WhereIf(name != null,
d => d.Name != null && d.Name.Contains(name))
.WhereIf(version != null,
d => d.Version != null && d.Version == version)
.WhereIf(languageCode != null,
d => d.LanguageCode != null && d.LanguageCode == languageCode)
.WhereIf(fileName != null,
d => d.FileName != null && d.FileName.Contains(fileName))
.WhereIf(format != null,
d => d.Format != null && d.Format == format)
.WhereIf(creationTimeMin.HasValue,
d => d.CreationTime.Date >= creationTimeMin.Value.Date)
.WhereIf(creationTimeMax.HasValue,
d => d.CreationTime.Date <= creationTimeMax.Value.Date)
.WhereIf(lastUpdatedTimeMin.HasValue,
d => d.LastUpdatedTime.Date >= lastUpdatedTimeMin.Value.Date)
.WhereIf(lastUpdatedTimeMax.HasValue,
d => d.LastUpdatedTime.Date <= lastUpdatedTimeMax.Value.Date)
.WhereIf(lastSignificantUpdateTimeMin.HasValue,
d => d.LastSignificantUpdateTime != null && d.LastSignificantUpdateTime.Value.Date >= lastSignificantUpdateTimeMin.Value.Date)
.WhereIf(lastSignificantUpdateTimeMax.HasValue,
d => d.LastSignificantUpdateTime != null && d.LastSignificantUpdateTime.Value.Date <= lastSignificantUpdateTimeMax.Value.Date)
.WhereIf(lastCachedTimeMin.HasValue,
d => d.LastCachedTime.Date >= lastCachedTimeMin.Value.Date)
.WhereIf(lastCachedTimeMax.HasValue,
d => d.LastCachedTime.Date <= lastCachedTimeMax.Value.Date);
}
}
}

124
modules/docs/src/Volo.Docs.MongoDB/Volo/Docs/Documents/MongoDocumentRepository.cs

@ -43,33 +43,88 @@ namespace Volo.Docs.Documents
x.Version == version, cancellationToken: cancellationToken);
}
public async Task<List<Document>> GetAllAsync(Guid? projectId,
public async Task<List<Document>> GetAllAsync(
Guid? projectId,
string name,
string version,
string languageCode,
string fileName,
string format,
DateTime? creationTimeMin,
DateTime? creationTimeMax,
DateTime? lastUpdatedTimeMin,
DateTime? lastUpdatedTimeMax,
DateTime? lastSignificantUpdateTimeMin,
DateTime? lastSignificantUpdateTimeMax,
DateTime? lastCachedTimeMin,
DateTime? lastCachedTimeMax,
string sorting = null,
int maxResultCount = int.MaxValue,
int skipCount = 0,
CancellationToken cancellationToken = default)
{
return await
ApplyFilterForGetAll(GetMongoQueryable(), projectId, name, version, languageCode)
.OrderBy(string.IsNullOrWhiteSpace(sorting) ? "name asc" : sorting).As<IMongoQueryable<Document>>()
.PageBy<Document, IMongoQueryable<Document>>(skipCount, maxResultCount)
.ToListAsync(GetCancellationToken(cancellationToken));
ApplyFilterForGetAll(
GetMongoQueryable(),
projectId: projectId,
name: name,
version: version,
languageCode: languageCode,
format: format,
fileName: fileName,
creationTimeMin: creationTimeMin,
creationTimeMax: creationTimeMax,
lastUpdatedTimeMin: lastUpdatedTimeMin,
lastUpdatedTimeMax: lastUpdatedTimeMax,
lastSignificantUpdateTimeMin: lastSignificantUpdateTimeMin,
lastSignificantUpdateTimeMax: lastSignificantUpdateTimeMax,
lastCachedTimeMin: lastCachedTimeMin,
lastCachedTimeMax: lastCachedTimeMax)
.OrderBy(string.IsNullOrWhiteSpace(sorting) ? "name asc" : sorting).As<IMongoQueryable<Document>>()
.PageBy<Document, IMongoQueryable<Document>>(skipCount, maxResultCount)
.ToListAsync(GetCancellationToken(cancellationToken));
}
public async Task<long> GetAllCountAsync(Guid? projectId,
public async Task<long> GetAllCountAsync(
Guid? projectId,
string name,
string version,
string languageCode,
string fileName,
string format,
DateTime? creationTimeMin,
DateTime? creationTimeMax,
DateTime? lastUpdatedTimeMin,
DateTime? lastUpdatedTimeMax,
DateTime? lastSignificantUpdateTimeMin,
DateTime? lastSignificantUpdateTimeMax,
DateTime? lastCachedTimeMin,
DateTime? lastCachedTimeMax,
string sorting = null,
int maxResultCount = int.MaxValue,
int skipCount = 0,
CancellationToken cancellationToken = default)
{
return await
ApplyFilterForGetAll(GetMongoQueryable(), projectId, name, version, languageCode)
ApplyFilterForGetAll(
GetMongoQueryable(),
projectId: projectId,
name: name,
version: version,
languageCode: languageCode,
format: format,
fileName: fileName,
creationTimeMin: creationTimeMin,
creationTimeMax: creationTimeMax,
lastUpdatedTimeMin: lastUpdatedTimeMin,
lastUpdatedTimeMax: lastUpdatedTimeMax,
lastSignificantUpdateTimeMin: lastSignificantUpdateTimeMin,
lastSignificantUpdateTimeMax: lastSignificantUpdateTimeMax,
lastCachedTimeMin: lastCachedTimeMin,
lastCachedTimeMax: lastCachedTimeMax)
.OrderBy(string.IsNullOrWhiteSpace(sorting) ? "name asc" : sorting).As<IMongoQueryable<Document>>()
.PageBy<Document, IMongoQueryable<Document>>(skipCount, maxResultCount)
.LongCountAsync(GetCancellationToken(cancellationToken));
@ -86,6 +141,16 @@ namespace Volo.Docs.Documents
string name,
string version,
string languageCode,
string fileName,
string format,
DateTime? creationTimeMin,
DateTime? creationTimeMax,
DateTime? lastUpdatedTimeMin,
DateTime? lastUpdatedTimeMax,
DateTime? lastSignificantUpdateTimeMin,
DateTime? lastSignificantUpdateTimeMax,
DateTime? lastCachedTimeMin,
DateTime? lastCachedTimeMax,
CancellationToken cancellationToken = default)
{
if (projectId.HasValue)
@ -108,6 +173,51 @@ namespace Volo.Docs.Documents
query = query.Where(d => d.LanguageCode != null && d.LanguageCode == languageCode);
}
if (fileName != null)
{
query = query.Where(d => d.FileName != null && d.FileName.Contains(fileName));
}
if (creationTimeMin.HasValue)
{
query = query.Where(d => d.CreationTime.Date >= creationTimeMin.Value.Date);
}
if (creationTimeMax.HasValue)
{
query = query.Where(d => d.CreationTime.Date <= creationTimeMax.Value.Date);
}
if (lastUpdatedTimeMin.HasValue)
{
query = query.Where(d => d.LastUpdatedTime.Date >= lastUpdatedTimeMin.Value.Date);
}
if (lastUpdatedTimeMax.HasValue)
{
query = query.Where(d => d.LastUpdatedTime.Date <= lastUpdatedTimeMax.Value.Date);
}
if (lastSignificantUpdateTimeMin.HasValue)
{
query = query.Where(d => d.LastSignificantUpdateTime != null && d.LastSignificantUpdateTime.Value.Date >= lastSignificantUpdateTimeMin.Value.Date);
}
if (lastSignificantUpdateTimeMax.HasValue)
{
query = query.Where(d => d.LastSignificantUpdateTime != null && d.LastSignificantUpdateTime.Value.Date <= lastSignificantUpdateTimeMax.Value.Date);
}
if (lastCachedTimeMin.HasValue)
{
query = query.Where(d => d.LastCachedTime.Date >= lastCachedTimeMin.Value.Date);
}
if (lastCachedTimeMax.HasValue)
{
query = query.Where(d => d.LastCachedTime.Date <= lastCachedTimeMax.Value.Date);
}
return query;
}
}

155
modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/Index.cshtml

@ -131,10 +131,10 @@
<div class="version-select">
<div class="input-group">
@*<div class="input-group-prepend">
<label class="input-group-text">
<i class="fa fa-globe" aria-hidden="true" data-toggle="tooltip" title="@L["Language"]"></i>
</label>
</div>*@
<label class="input-group-text">
<i class="fa fa-globe" aria-hidden="true" data-toggle="tooltip" title="@L["Language"]"></i>
</label>
</div>*@
<select asp-items="Model.LanguageSelectListItems"
class="form-control"
onchange="window.location.replace(this.value)">
@ -163,25 +163,6 @@
</div>
</div>
@if (Model.FullSearchEnabled)
{
<div class="docs-version mt-2 mb-4">
<div class="version-select">
<div class="input-group">
<div class="input-group-prepend">
<label class="input-group-text"><i class="fa fa-search"></i></label>
</div>
<input class="form-control"
id="fullsearch"
type="search"
data-fullsearch-url="/search/@Model.LanguageCode/@Model.ProjectName/@Model.Version/"
placeholder="@L["FullSearch"].Value"
aria-label="Filter">
</div>
</div>
</div>
}
@if (Model.Navigation == null || !Model.Navigation.HasChildItems)
{
@ -209,48 +190,60 @@
{
<div class="col-md-7 docs-content bg-white">
<div class="docs-link-btns">
<div class="float-left">
@(L["ShareOn"].Value + " :")
<a href="#" target="_blank" class="share-button twitter" id="TwitterShareLink" title="Twitter">
<i class="fa fa-twitter"></i>
</a>
<a href="#" target="_blank" class="share-button linkedin" id="LinkedinShareLink" title="LinkedIn">
<i class="fa fa-linkedin"></i>
</a>
<a href="#" target="_blank" class="share-button email" id="EmailShareLink" title="E-mail">
<i class="fa fa-envelope-square"></i>
</a>
</div>
<div class="float-right">
@if (!string.IsNullOrEmpty(Model.Document.EditLink))
{
<a href="@Model.Document.EditLink" target="_blank">
<i class="fa fa-edit"></i>
@(L["Edit"])
<span class="for-desktop">(@L["LastEditTime"]: @Model.Document.LastUpdatedTime.ToShortDateString())</span>
</a>
}
</div>
<div class="row">
<div class="col">
@if (Model.FullSearchEnabled)
{
<div class="search-area">
<div class="input-group">
<div class="input-group-prepend">
<label class="input-group-text"><i class="fa fa-search"></i></label>
</div>
<div class="float-right mr-3">
@if (Model.Document.Contributors != null && Model.Document.Contributors.Count > 0)
{
<span class="for-desktop">
@(L["Contributors"].Value + " :") </span>
@foreach (var contributor in Model.Document.Contributors)
<input class="form-control"
id="fullsearch"
type="search"
data-fullsearch-url="/search/@Model.LanguageCode/@Model.ProjectName/@Model.Version/"
placeholder="@L["FullSearch"].Value"
aria-label="Filter">
</div>
</div>
}
</div>
<div class="col-auto">
<div class="cont-container">
@if (Model.Document.Contributors != null && Model.Document.Contributors.Count > 0)
{
<span class="for-desktop mr-3">
@(L["Contributors"].Value)
</span>
@foreach (var contributor in Model.Document.Contributors)
{
<a href="@contributor.UserProfileUrl" target="_blank" class="cont-avatar">
<img src="@contributor.AvatarUrl"
class="rounded-circle"
alt="Avatar"
height="21"
width="21"
title="@contributor.Username" />
</a>
}
}
</div>
</div>
<div class="col-auto">
@if (!string.IsNullOrEmpty(Model.Document.EditLink))
{
<a href="@contributor.UserProfileUrl" target="_blank">
<img src="@contributor.AvatarUrl"
class="rounded-circle"
alt="Avatar"
height="21"
width="21"
title="@contributor.Username" />
<a href="@Model.Document.EditLink" target="_blank">
<i class="fa fa-edit"></i>
@(L["Edit"])
<span class="for-desktop text-muted">@L["LastEditTime"]: @Model.Document.LastUpdatedTime.ToShortDateString()</span>
</a>
}
}
</div>
</div>
</div>
</div>
@ -318,8 +311,20 @@
</div>
</div>
</div>
<!-- Right Bar -->
<div class="col-md-2 docs-page-index position-relative bg-light">
<div class="doc-social-btns">
@(L["ShareOn"].Value + " :")
<a href="#" target="_blank" class="share-button twitter" id="TwitterShareLink" title="Twitter">
<i class="fa fa-twitter"></i>
</a>
<a href="#" target="_blank" class="share-button linkedin" id="LinkedinShareLink" title="LinkedIn">
<i class="fa fa-linkedin"></i>
</a>
<a href="#" target="_blank" class="share-button email" id="EmailShareLink" title="E-mail">
<i class="fa fa-envelope-square"></i>
</a>
</div>
<div id="scroll-index" class="docs-inner-anchors mt-2">
<h5>@L["InThisDocument"]</h5>
<nav id="docs-sticky-index" class="navbar index-scroll">
@ -350,17 +355,17 @@
else
{
if (!Model.ProjectFound)
{
@(await Component.InvokeAsync<ErrorViewComponent>(new
{
model = new ErrorPageModel
{
RedirectUrl = Model.DocumentsUrlPrefix,
ErrorCode = "404",
ErrorMessage = L.GetString("ProjectNotFound")
}
}))
}
{
@(await Component.InvokeAsync<ErrorViewComponent>(new
{
model = new ErrorPageModel
{
RedirectUrl = Model.DocumentsUrlPrefix,
ErrorCode = "404",
ErrorMessage = L.GetString("ProjectNotFound")
}
}))
}
if (!Model.DocumentFound)
{
@ -370,9 +375,9 @@ else
{
RedirectUrl = Model.DocumentsUrlPrefix + Model.LanguageCode + "/" + Model.ProjectName + "/"
+ (Model.LatestVersionInfo.IsSelected ? DocsAppConsts.Latest : Model.Version),
ErrorCode = "404",
ErrorCode = "404",
ErrorMessage = L.GetString("DocumentNotFound"),
AutoRedirect = !Model.DocumentName.IsNullOrWhiteSpace()
AutoRedirect = !Model.DocumentName.IsNullOrWhiteSpace()
}
}))
}

6
modules/docs/src/Volo.Docs.Web/Pages/Documents/Shared/Scripts/vs.js

@ -109,11 +109,13 @@
var wWidth = $(window).width();
if (wWidth > 766) {
$("#sidebar-scroll").mCustomScrollbar({
theme: "minimal"
theme: "minimal",
alwaysShowScrollbar: 0,
});
$("#scroll-index").mCustomScrollbar({
theme: "minimal-dark"
theme: "minimal-dark",
alwaysShowScrollbar: 0,
});
}
}

89
modules/docs/src/Volo.Docs.Web/Pages/Documents/Shared/Styles/vs.css

@ -65,10 +65,12 @@
height: 100vh; }
.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list > ul {
display: block;
height: calc(100vh - 320px);
overflow-y: auto; }
height: calc(100vh - 230px);
overflow-y: auto;
margin-right: 12px !important;
margin-top: 20px !important; }
.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list ul {
font-size: .935em;
font-size: .9em;
list-style: none;
padding: 0 1rem;
margin: 0; }
@ -179,26 +181,34 @@
.docs-page .docs-content .contributors a:hover {
text-decoration: none; }
.docs-page .docs-content .docs-link-btns {
border-bottom: 1px solid #f4f5f7;
background: #fdfdfd;
padding: 10px 20px;
background: #f5f7fa;
padding: 15px 30px;
margin: 0 -15px;
text-align: right;
font-size: .8em;
min-height: 40px; }
min-height: 48px; }
.docs-page .docs-content .docs-link-btns a {
color: #999; }
color: #222; }
.docs-page .docs-content .docs-link-btns a .text-muted {
color: #ccc !important; }
.docs-page .docs-content .docs-link-btns a:hover {
color: #444;
color: #000;
text-decoration: none; }
.docs-page .docs-content .docs-link-btns .twitter {
color: #00ACEE; }
.docs-page .docs-content .docs-link-btns .linkedin {
color: #0077B5; }
.docs-page .docs-content .docs-link-btns .email {
color: #5a5a5a; }
.docs-page .docs-content .docs-link-btns .share-button {
margin-left: 10px; }
.docs-page .docs-content .docs-link-btns .search-area {
margin: -5px 0 -5px -10px;
box-shadow: 0 0 10px #e8e8e8; }
.docs-page .docs-content .docs-link-btns .search-area .input-group-text {
background: white;
border: 0;
color: #000;
font-size: 1em; }
.docs-page .docs-content .docs-link-btns .search-area .form-control {
background: #fff;
border: 0;
font-size: 1em;
padding-left: 0;
outline: 0;
box-shadow: none; }
.docs-page .docs-content .docs-text-field {
padding: 2rem; }
.docs-page .docs-content article.docs-body {
@ -259,13 +269,46 @@
background-color: #f6f8fa; }
.docs-page .docs-content article.docs-body table img {
background-color: initial; }
.docs-page .doc-social-btns {
margin: 0 -15px 0;
font-size: .8em;
background: #e9ecf0;
height: 53px;
padding: 15px 20px;
position: fixed;
top: 0px;
width: 100%; }
.docs-page .doc-social-btns a:hover {
text-decoration: none; }
.docs-page .doc-social-btns .twitter {
color: #00ACEE; }
.docs-page .doc-social-btns .linkedin {
color: #0077B5; }
.docs-page .doc-social-btns .email {
color: #5a5a5a; }
.docs-page .doc-social-btns .share-button {
margin-left: 10px; }
.docs-page .cont-container a.cont-avatar {
position: relative; }
.docs-page .cont-container a.cont-avatar img {
width: 24px;
height: 24px;
box-shadow: 0 0 8px #c1bbbb;
border: 2px solid #fff;
margin-left: -10px;
display: inline-block;
margin-top: -2px;
transition: .2s; }
.docs-page .cont-container:hover a.cont-avatar img {
margin-left: -2px; }
.docs-page .docs-page-index {
min-height: 96vh; }
min-height: 90vh;
background-color: #f5f7fa !important; }
.docs-page .docs-page-index #scroll-index {
max-height: 96vh; }
max-height: 90vh; }
.docs-page .docs-page-index .docs-inner-anchors {
position: fixed;
top: 0px;
top: 50px;
padding: 10px;
font-size: .90em; }
.docs-page .docs-page-index .docs-inner-anchors .navbar .nav-pills {
@ -617,3 +660,9 @@ div.code-toolbar > .toolbar a {
margin-left: -36px; } }
.scrolledMore .alert-criteria p.alert-p {
display: none; }
.mCS-autoHide > .mCustomScrollBox > .mCSB_scrollTools,
.mCS-autoHide > .mCustomScrollBox ~ .mCSB_scrollTools {
opacity: 1 !important;
filter: "alpha(opacity=1)";
-ms-filter: "alpha(opacity=1)"; }

2
modules/docs/src/Volo.Docs.Web/Pages/Documents/Shared/Styles/vs.min.css

File diff suppressed because one or more lines are too long

131
modules/docs/src/Volo.Docs.Web/Pages/Documents/Shared/Styles/vs.scss

@ -26,7 +26,7 @@ body {
left: 0;
position: fixed;
background: #1d1d1d;
.input-group {
border-radius: 5px;
overflow: hidden;
@ -103,12 +103,14 @@ body {
> ul {
display: block;
height: calc(100vh - 320px);
height: calc(100vh - 230px);
overflow-y: auto;
margin-right: 12px !important;
margin-top: 20px !important;
}
ul {
font-size: .935em;
font-size: .9em;
list-style: none;
padding: 0 1rem;
margin: 0;
@ -298,37 +300,45 @@ body {
}
.docs-link-btns {
border-bottom: 1px solid #f4f5f7;
background: #fdfdfd;
padding: 10px 20px;
background: #f5f7fa;
padding: 15px 30px;
margin: 0 -15px;
text-align: right;
font-size: .8em;
min-height: 40px;
min-height: 48px;
a {
color: #999;
color: #222;
.text-muted {
color: #ccc !important;
}
&:hover {
color: #444;
color: #000;
text-decoration: none;
}
}
.twitter {
color: #00ACEE;
}
.linkedin {
color: #0077B5;
}
.search-area {
margin: -5px 0 -5px -10px;
box-shadow: 0 0 10px #e8e8e8;
.email {
color: #5a5a5a;
}
.input-group-text {
background: white;
border: 0;
color: #000;
font-size: 1em;
}
.share-button {
margin-left: 10px;
.form-control {
background: #fff;
border: 0;
font-size: 1em;
padding-left: 0;
outline: 0;
box-shadow: none;
}
}
}
@ -432,16 +442,73 @@ body {
}
}
.doc-social-btns {
margin: 0 -15px 0;
font-size: .8em;
background: #e9ecf0;
height: 53px;
padding: 15px 20px;
position: fixed;
top: 0px;
width: 100%;
a:hover {
text-decoration: none;
}
.twitter {
color: #00ACEE;
}
.linkedin {
color: #0077B5;
}
.email {
color: #5a5a5a;
}
.share-button {
margin-left: 10px;
}
}
.cont-container {
a.cont-avatar {
position: relative;
img {
width: 24px;
height: 24px;
box-shadow: 0 0 8px #c1bbbb;
border: 2px solid #fff;
margin-left: -10px;
display: inline-block;
margin-top: -2px;
transition: .2s;
}
}
&:hover {
a.cont-avatar {
img {
margin-left: -2px;
}
}
}
}
.docs-page-index {
min-height: 96vh;
min-height: 90vh;
background-color: #f5f7fa !important;
#scroll-index {
max-height: 96vh;
max-height: 90vh;
}
.docs-inner-anchors {
position: fixed;
top: 0px;
top: 50px;
padding: 10px;
font-size: .90em;
@ -517,11 +584,11 @@ body {
.docs-page {
.docs-sidebar {
.docs-sidebar {
.docs-sidebar-wrapper {
.docs-version {
.version-select {
.version-select {
select.form-control, input.form-control {
background: #000000;
@ -696,7 +763,6 @@ body {
.container {
max-width: 1080px;
}
}
@media (min-width: 1366px) {
@ -960,7 +1026,7 @@ div.code-toolbar > .toolbar a {
@media screen and (max-width: 767px) {
.navbar-logo {
.navbar-brand {
display: inline-block;
display: inline-block;
margin: 0 auto !important;
max-width: 70%;
overflow: hidden;
@ -1012,6 +1078,7 @@ div.code-toolbar > .toolbar a {
}
}
}
.scrolledMore {
padding-top: 107px;
@ -1034,4 +1101,10 @@ div.code-toolbar > .toolbar a {
}
}
}
.mCS-autoHide > .mCustomScrollBox > .mCSB_scrollTools,
.mCS-autoHide > .mCustomScrollBox ~ .mCSB_scrollTools {
opacity: 1 !important;
filter: "alpha(opacity=1)";
-ms-filter: "alpha(opacity=1)";
}

4
modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/AbpIdentityDomainModule.cs

@ -4,7 +4,7 @@ using Microsoft.Extensions.DependencyInjection.Extensions;
using Microsoft.Extensions.Options;
using Volo.Abp.AutoMapper;
using Volo.Abp.Domain;
using Volo.Abp.EventBus.Distributed;
using Volo.Abp.Domain.Entities.Events.Distributed;
using Volo.Abp.Modularity;
using Volo.Abp.ObjectExtending;
using Volo.Abp.ObjectExtending.Modularity;
@ -29,7 +29,7 @@ namespace Volo.Abp.Identity
options.AddProfile<IdentityDomainMappingProfile>(validate: true);
});
Configure<AbpDistributedEventBusOptions>(options =>
Configure<AbpDistributedEntityEventOptions>(options =>
{
options.EtoMappings.Add<IdentityUser, UserEto>(typeof(AbpIdentityDomainModule));
options.EtoMappings.Add<IdentityClaimType, IdentityClaimTypeEto>(typeof(AbpIdentityDomainModule));

9
modules/identity/test/Volo.Abp.Identity.Domain.Tests/Volo/Abp/Identity/AbpIdentityDomainTestModule.cs

@ -1,5 +1,6 @@
using Microsoft.Extensions.DependencyInjection;
using Volo.Abp.Authorization.Permissions;
using Volo.Abp.Domain.Entities.Events.Distributed;
using Volo.Abp.Identity.EntityFrameworkCore;
using Volo.Abp.Modularity;
using Volo.Abp.PermissionManagement.Identity;
@ -14,6 +15,14 @@ namespace Volo.Abp.Identity
)]
public class AbpIdentityDomainTestModule : AbpModule
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
Configure<AbpDistributedEntityEventOptions>(options =>
{
options.AutoEventSelectors.Add<IdentityUser>();
});
}
public override void OnApplicationInitialization(ApplicationInitializationContext context)
{
SeedTestData(context);

15
modules/identity/test/Volo.Abp.Identity.Domain.Tests/Volo/Abp/Identity/Distributed_User_Change_Event_Tests.cs

@ -2,6 +2,7 @@
using Microsoft.AspNetCore.Identity;
using Microsoft.Extensions.Options;
using Shouldly;
using Volo.Abp.Domain.Entities.Events.Distributed;
using Volo.Abp.EventBus.Distributed;
using Volo.Abp.Testing.Utils;
using Volo.Abp.Uow;
@ -28,11 +29,17 @@ namespace Volo.Abp.Identity
}
[Fact]
public async Task Should_Register_Handler()
public void Should_Register_Handler()
{
var options = GetRequiredService<IOptions<AbpDistributedEventBusOptions>>().Value;
options.EtoMappings.ShouldContain(m => m.Key == typeof(IdentityUser) && m.Value.EtoType == typeof(UserEto));
options.Handlers.ShouldContain(h => h == typeof(DistributedUserUpdateHandler));
GetRequiredService<IOptions<AbpDistributedEntityEventOptions>>()
.Value
.EtoMappings
.ShouldContain(m => m.Key == typeof(IdentityUser) && m.Value.EtoType == typeof(UserEto));
GetRequiredService<IOptions<AbpDistributedEventBusOptions>>()
.Value
.Handlers
.ShouldContain(h => h == typeof(DistributedUserUpdateHandler));
}
[Fact]

4
modules/identityserver/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/AbpIdentityServerDomainModule.cs

@ -6,7 +6,7 @@ using Microsoft.Extensions.Options;
using Volo.Abp.AutoMapper;
using Volo.Abp.BackgroundWorkers;
using Volo.Abp.Caching;
using Volo.Abp.EventBus.Distributed;
using Volo.Abp.Domain.Entities.Events.Distributed;
using Volo.Abp.Identity;
using Volo.Abp.IdentityServer.ApiResources;
using Volo.Abp.IdentityServer.Clients;
@ -41,7 +41,7 @@ namespace Volo.Abp.IdentityServer
options.AddProfile<IdentityServerAutoMapperProfile>(validate: true);
});
Configure<AbpDistributedEventBusOptions>(options =>
Configure<AbpDistributedEntityEventOptions>(options =>
{
options.EtoMappings.Add<ApiResource, ApiResourceEto>(typeof(AbpIdentityServerDomainModule));
options.EtoMappings.Add<Client, ClientEto>(typeof(AbpIdentityServerDomainModule));

4
modules/tenant-management/src/Volo.Abp.TenantManagement.Domain/Volo/Abp/TenantManagement/AbpTenantManagementDomainModule.cs

@ -2,7 +2,7 @@
using Volo.Abp.AutoMapper;
using Volo.Abp.Data;
using Volo.Abp.Domain;
using Volo.Abp.EventBus.Distributed;
using Volo.Abp.Domain.Entities.Events.Distributed;
using Volo.Abp.Modularity;
using Volo.Abp.MultiTenancy;
using Volo.Abp.UI;
@ -26,7 +26,7 @@ namespace Volo.Abp.TenantManagement
options.AddProfile<AbpTenantManagementDomainMappingProfile>(validate: true);
});
Configure<AbpDistributedEventBusOptions>(options =>
Configure<AbpDistributedEntityEventOptions>(options =>
{
options.EtoMappings.Add<Tenant, TenantEto>();
});

12
modules/virtual-file-explorer/src/Volo.Abp.VirtualFileExplorer.Web/Localization/Resources/tr.json

@ -1,6 +1,14 @@
{
"culture": "tr",
"texts": {
"VirtualFileExplorer": "Sanal dosya gezgini",
"VirtualFileType": "Sanal dosya tipi",
"Menu:VirtualFileExplorer": "Sanal dosya gezgini ",
"LastUpdateTime": "Son güncelleme zamanı",
"VirtualFileName": "Sanal dosya adı",
"FileContent": "Dosyaa içeriği",
"Size": "Boyut",
"BackToRoot": "Kök'e dön",
"EmptyFileInfoList": "Sanal dosyalar yok"
}
}
}

7
npm/ng-packs/packages/core/src/lib/services/list.service.ts

@ -1,6 +1,6 @@
import { Inject, Injectable, OnDestroy, Optional } from '@angular/core';
import { BehaviorSubject, Observable, ReplaySubject } from 'rxjs';
import { debounceTime, shareReplay, switchMap, tap } from 'rxjs/operators';
import { BehaviorSubject, Observable, of, ReplaySubject } from 'rxjs';
import { catchError, debounceTime, filter, shareReplay, switchMap, tap } from 'rxjs/operators';
import { ABP } from '../models/common';
import { PagedResultDto } from '../models/dtos';
import { LIST_QUERY_DEBOUNCE_TIME } from '../tokens/list.token';
@ -88,7 +88,8 @@ export class ListService<QueryParamsType = ABP.PageQueryParams> implements OnDes
this._isLoading$.next(true);
return this.query$.pipe(
switchMap(streamCreatorCallback),
switchMap(query => streamCreatorCallback(query).pipe(catchError(() => of(null)))),
filter(Boolean),
tap(() => this._isLoading$.next(false)),
shareReplay({ bufferSize: 1, refCount: true }),
takeUntilDestroy(this),

13
npm/ng-packs/packages/theme-shared/src/lib/directives/ngx-datatable-list.directive.ts

@ -36,8 +36,15 @@ export class NgxDatatableListDirective implements OnChanges, OnDestroy, OnInit {
private subscribeToSort() {
const sub = this.table.sort.subscribe(({ sorts: [{ prop, dir }] }) => {
this.list.sortKey = prop;
this.list.sortOrder = dir;
if (prop === this.list.sortKey && this.list.sortOrder === 'desc') {
this.list.sortKey = '';
this.list.sortOrder = '';
this.table.sorts = [];
this.cdRef.detectChanges();
} else {
this.list.sortKey = prop;
this.list.sortOrder = dir;
}
});
this.subscription.add(sub);
}
@ -45,7 +52,7 @@ export class NgxDatatableListDirective implements OnChanges, OnDestroy, OnInit {
private subscribeToIsLoading() {
const sub = this.list.isLoading$.subscribe(loading => {
this.table.loadingIndicator = loading;
this.cdRef.markForCheck();
this.cdRef.detectChanges();
});
this.subscription.add(sub);
}

1
samples/MicroserviceDemo/applications/BackendAdminApp.Host/BackendAdminAppHostModule.cs

@ -8,7 +8,6 @@ using ProductManagement;
using StackExchange.Redis;
using Microsoft.OpenApi.Models;
using MsDemo.Shared;
using Swashbuckle.AspNetCore.Swagger;
using Volo.Abp;
using Volo.Abp.AspNetCore.Authentication.OAuth;
using Volo.Abp.AspNetCore.Mvc.Client;

6
samples/MicroserviceDemo/microservices/IdentityService.Host/IdentityServiceHostModule.cs

@ -13,6 +13,7 @@ using Volo.Abp.AspNetCore.Mvc;
using Volo.Abp.Auditing;
using Volo.Abp.AuditLogging.EntityFrameworkCore;
using Volo.Abp.Autofac;
using Volo.Abp.Domain.Entities.Events.Distributed;
using Volo.Abp.EntityFrameworkCore;
using Volo.Abp.EntityFrameworkCore.SqlServer;
using Volo.Abp.EventBus.RabbitMq;
@ -77,6 +78,11 @@ namespace IdentityService.Host
{
options.UseSqlServer();
});
Configure<AbpDistributedEntityEventOptions>(options =>
{
options.AutoEventSelectors.Add<IdentityUser>();
});
context.Services.AddStackExchangeRedisCache(options =>
{

10
samples/MicroserviceDemo/modules/product/src/ProductManagement.Application.Contracts/ProductManagement/Localization/ApplicationContracts/tr.json

@ -0,0 +1,10 @@
{
"culture": "tr",
"texts": {
"Permission:ProductManagement": "Ürün Yönetimi",
"Permission:Products": "Ürünler",
"Permission:Edit": "Güncelle",
"Permission:Delete": "Sil",
"Permission:Create": "Oluştur"
}
}

16
samples/MicroserviceDemo/modules/product/src/ProductManagement.Web/Localization/Resources/ProductManagement/tr.json

@ -0,0 +1,16 @@
{
"culture": "tr",
"texts": {
"Menu:ProductManagement": "Ürün Yönetimi",
"Menu:Products": "Ürünler",
"ProductManagement": "Ürün Yönetimi",
"CreateANewProduct": "Yeni Bir Ürün Oluştur",
"Products": "Ürünler",
"StockCount": "Stok Sayısı",
"Code": "Kod",
"Name": "İsim",
"Price": "Fiyat",
"ImageName": "Fotoğraf İsmi",
"ProductDeletionWarningMessage": "Bu ürünü silmek istediğinize emin misiniz?"
}
}
Loading…
Cancel
Save