diff --git a/.gitignore b/.gitignore index 3f8d0ff6cb..ccb98f81a0 100644 --- a/.gitignore +++ b/.gitignore @@ -323,3 +323,7 @@ deploy/npm-auth-token.txt deploy/ssh-password.txt deploy/github-api-key.txt deploy/_run_all_log.txt + + +# No commit yarn.lock files in the subfolders of templates directory +templates/**/yarn.lock \ No newline at end of file diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Admin/Localization/Resources/zh-Hans.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Admin/Localization/Resources/zh-Hans.json index bb2e4077cc..b363aa0c64 100644 --- a/abp_io/AbpIoLocalization/AbpIoLocalization/Admin/Localization/Resources/zh-Hans.json +++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Admin/Localization/Resources/zh-Hans.json @@ -316,14 +316,12 @@ "TrialLicenseStatusFilter": "地位", "TrialLicenseStartDateFilter": "开始日期", "TrialLicenseEndDateFilter": "结束日期", - "FirsName": "名", + "FirstName": "名字", "LastName": "姓", "StartDate": "开始日期", "EndDate": "结束日期", "PurchasedDate": "购买日期", "OrganizationDetail": "组织详情", - "SendActivationMail": "发送激活邮件", - "ActivationMailSentSuccessfully": "激活邮件发送成功!", "TrialLicenseStatus": "试用许可证状态", "TrialLicenseDetail": "试用许可证详情", "AcceptsMarketingCommunications": "营销传播", @@ -337,17 +335,68 @@ "Expired": "已到期", "TrialLicenseDeletionWarningMessage": "您确定要删除试用许可证吗?试用许可证、组织、支持帐户将被删除!", "LicenseCategoryFilter": "执照类别", - "Volo.AbpIo.Commercial:030000": "您已经使用了试用期。", - "Volo.AbpIo.Commercial:030001": "此组织名称已存在。", - "Volo.AbpIo.Commercial:030002": "一旦激活,试用许可证不能设置为请求!", - "Volo.AbpIo.Commercial:030003": "没有这种状态!", - "Volo.AbpIo.Commercial:030004": "由于意外错误,无法更改状态!", - "Volo.AbpIo.Commercial:030005": "当试用许可证处于 -activated- 状态时,可以更新开始和结束日期!", - "Volo.AbpIo.Commercial:030006": "结束日期必须始终大于开始日期!", - "Volo.AbpIo.Commercial:030007": "此试用许可证已激活一次!", - "Volo.AbpIo.Commercial:030008": "购买日期只能在状态为已购买时设置!", - "Volo.AbpIo.Commercial:030009": "未找到用户!", - "Volo.AbpIo.Commercial:030010": "要购买试用许可证,首先您需要激活您的试用许可证!", - "Volo.AbpIo.Commercial:030011": "购买后,您无法删除试用许可证!" + "Permission:SendWelcomeEmail": "发送欢迎邮件", + "SendWelcomeEmail": "发送欢迎邮件", + "SendWelcomeEmailWarningMessage": "你确定要发送欢迎邮件给组织成员吗?", + "SendWelcomeEmailSuccessMessage": "欢迎邮件发送成功!", + "Activate": "激活", + "ActivateTrialLicenseWarningMessage": "激活试用版权限后,将发送欢迎邮件给用户。你确定要激活吗?", + "ActivateTrialLicenseSuccessMessage": "激活成功,欢迎邮件已发送给组织成员。", + "PaymentRequestId": "付款请求编号", + "AdditionalDeveloperCount": "额外开发者数量", + "LicensePrice": "版权价格", + "PurchaseDate": "购买日期", + "IsAbpBookDownloaded": "ABP书籍已下载", + "IsMasteringAbpBookDownloadEnabled": "ABP书籍下载已启用", + "Permission:Accounting:CustomPaymentLinkGenerator": "自定义付款链接", + "CustomPaymentLink": "自定义付款链接", + "Menu:CustomPaymentLink": "自定义付款链接", + "Amount": "金额", + "GenerateCustomPaymentLink": "生成自定义付款链接", + "GeneratedPaymentLink": "生成的付款链接", + "CopyText": "复制文本", + "Permission:CommunityEvents": "活动", + "Menu:Events": "活动", + "Events": "活动", + "EventType": "活动类型", + "Number": "数量", + "RegistrationURL": "报名网址", + "URL": "网址", + "EventDeletionConfirmationMessage": "你确定要删除这个活动吗?", + "Enum:EventType:0": "社区讲话", + "CreateAnEvent": "创建一个活动", + "Permission:CommunitySpeakers": "演讲者", + "CreateASpeaker": "创建一个演讲者", + "Speakers": "演讲者", + "Image": "图片", + "GithubURL": "Github网址", + "SpeakerDeletionConfirmationMessage": "你确定要删除这个演讲者吗?", + "Menu:Speakers": "演讲者", + "ChooseSpeakerImage": "选择一个演讲者图片...", + "SpeakerImage": "演讲者图片", + "AddSpeaker": "添加演讲者", + "ShowPurchaseItemsOfOrganizations": "购买项目", + "Enum:OrganizationPurchaseState:0": "未送达", + "Enum:OrganizationPurchaseState:1": "已送达", + "PurchaseItems": "购买项目", + "SuccessfullyUpdated": "成功更新", + "SuccessfullyAdded": "成功添加", + "PurchaseState": "购买状态", + "ShowBetweenDayCount": "显示之间的天数", + "PurchaseOrder": "购买订单", + "ShowCreateInvoiceOfOrganization": "创建发票", + "ShowCreateQuotationOfOrganization": "创建报价单", + "BookDiscounts": "书籍折扣", + "Permission:BookDiscount": "书籍折扣", + "Menu:BookDiscounts": "书籍折扣", + "BookType": "书籍类型", + "PurchasePlatform": "购买平台", + "StartTime": "开始时间", + "EndTime": "结束时间", + "CreateABookDiscount": "创建一个书籍折扣", + "BookDiscountDeletionConfirmationMessage": "你确定要删除这个书籍折扣吗?", + "CustomPaymentFlexSwitchDescription": "授权", + "AllowFeatureUpgradeOnLicenseExpire": "允许在授权过期时进行功能升级", + "Deleted{0}": "[已删除 {0}]" } } \ No newline at end of file diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Base/Localization/Resources/zh-Hans.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Base/Localization/Resources/zh-Hans.json index e1ad37704f..52358fb0ed 100644 --- a/abp_io/AbpIoLocalization/AbpIoLocalization/Base/Localization/Resources/zh-Hans.json +++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Base/Localization/Resources/zh-Hans.json @@ -164,6 +164,9 @@ "Error_Page_500_Description_1": "我们会自动跟踪这些错误,但如果问题仍然存在,请随时
联系我们。 与此同时,尝试刷新。", "Error_Page_500_Description_2": "通过 info@abp.io 与我们联系。", "Books": "书籍", + "ABPDiscordServer": "ABP Discord 服务器", + "ABPCommunityTalks": "ABP社区讲话", + "ABPCommunityPosts": "ABP社区文章", "BuyAndGetMonths": "购买 12 个月,获得 14 个月!", "GetYourDeal": "得到你的交易", "BuyOrRenewLicense": "立即购买或续订许可证并额外获得 2 个月!", diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/zh-Hans.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/zh-Hans.json index 0d67d9cca5..0663bcfb6b 100644 --- a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/zh-Hans.json +++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/zh-Hans.json @@ -137,7 +137,6 @@ "Success": "成功", "WeWillReplyYou": "你的消息已经发送! 我们会在短时间内给你答复.", "GoHome": "回到主页面", - "Home": "主页", "CreateLiveDemo": "创建在线演示", "RegisterToTheNewsletter": "注册到时事简报以获取有关ABP.IO的消息,比如新发布的内容.", "EnterYourEmailOrLogin": "输入你的e-mail地址来创建你的演示或者使用你的已有账号登录.", @@ -184,6 +183,7 @@ "ChangingLicenseType": "将来更改我的许可类型吗?", "ChangingLicenseTypeExplanation": "你始终可以在同一许可中添加新的开发人员. 参阅 \"有多少开发者可以参与ABP商业版工作?\". 你还可以通过支付计算出的价格差来升级到更高的许可. 当你升级到更高的许可计划时,可以享受新计划的好处,但是许可升级不会更改许可的到期日期.", "LicenseExtendUpgradeDiff": "许可扩展和升级有什么区别?", + "LicenseExtendUpgradeDiffExplanation": "延长: 你通过延长/续费你的许可证,你将继续获得高级支持和主要或次要更新模块和主题。除此之外,你还将继续创建新的项目。并且你仍然可以使用ABP Suite,这将加快你的开发。当你延长你的许可证时,1年将添加到你的许可证到期日。
升级: 你通过升级你的许可证,你将晋升到更高的许可证方案,这将允许你获得额外的奖励。查看许可证比较表来查看许可证方案之间的差异。但是,当你升级时,你的许可证到期日不会更改!要延长你的许可证结束日期,你需要延长你的许可证。", "LicenseRenewalCost": "一年后的许可续期费用是多少?", "LicenseRenewalCostExplanation": "标准 Team 许可证的续订(扩展)价格为 ${0},标准 Business License 为 ${1},标准 Enterprise License 为 ${2}。 如果您已经是客户,请登录您的帐户查看可用的续订价格。", "HowDoIRenewMyLicense": "如何续费我的许可证?", @@ -195,10 +195,19 @@ "IsSourceCodeIncludedExplanation4": "

将模块的源代码包含到解决方案中,可以最大程度地自定义该模块. 但是当新版本发布时,将无法自动升级模块.

这些许可均不包含ABP Suite源代码,该源代码是一个外部工具,可以为你生成代码并帮助你进行开发

有关许可类型之间的其它差异查看定价页面.

", "ChangingDevelopers": "我将来可以更改我组织的注册开发人员吗?", "ChangingDevelopersExplanation": "除了将新的开发人员添加到你的许可中之外,你还可以更改现有的开发人员(可以删除一个开发人员并将新的开发人员添加到同一位置),而无需任何额外费用.", + "WhatHappensWhenLicenseEnds": "我的许可证期间结束时,会发生什么?", + "WhatHappensWhenLicenseEndsExplanation1": "你的ABP商业许可证是一个永久许可证。你的许可证到期后,你可以继续开发你的项目。并且你不需要续费你的许可证。你的许可证是一年更新和支持方案默认的。为了继续获得新的功能,性能改进,修复,支持和继续使用ABP Suite,你需要续费你的许可证。你的许可证到期后,你将失去以下功能:", + "WhatHappensWhenLicenseEndsExplanation2": "你不能使用ABP商业创建新的解决方案,但是你可以继续开发你现有的应用程序。", + "WhatHappensWhenLicenseEndsExplanation3": "你将能够获得模块和主题的更新(除了RC或预览版本)。例如,如果你使用模块的v3.2.0版本,你仍然可以获得v3.2.x版本的更新(v3.2.1,v3.2.5...等等)。但是,你不能获得下一个主要或次要版本的更新(例如v3.3.0,v3.3.3,4.x.x...等等)。例如,你的许可证到期后,最新的发行是v4.4.3,之后,它发布了4.4.4版本和4.5.0版本,你将能够访问v4.4.X,但你不能访问v4.5.X。", + "WhatHappensWhenLicenseEndsExplanation4": "你不能在你的许可证到期后安装ABP商业平台上添加的新模块和主题。", + "WhatHappensWhenLicenseEndsExplanation5": "你不能使用ABP Suite。", + "WhatHappensWhenLicenseEndsExplanation6": "你不能再获得高级支持。", + "WhatHappensWhenLicenseEndsExplanation7": "如果你想继续获得这些奖励,你可以继续续费你的许可证。如果你在许可证到期后1个月内续费,将会应用以下折扣:团队许可证{0}%折扣,商业许可证{1}%折扣,企业许可证{2}%折扣。", "WhatHappensWhenLicenseEndsExplanation8": "您生成的 ABP 项目未存储在我们的服务器上。 因此,您有责任保留下载的源代码。 当您的许可证到期时,将无法获取您生成的 ABP 项目源代码。", "WhenShouldIRenewMyLicense": "我什么时候应该续订我的许可?", "WhenShouldIRenewMyLicenseExplanation": "如果您在许可证到期后 1 个月内续订许可证,将享受以下折扣:团队许可证 {0}% 折扣、商业许可证 {1}% 折扣、企业许可证 {2}% 折扣 . 如果您在许可证到期后 1 个月续订许可证,续订价格将与许可证购买价格相同,并且续订不会有折扣。", "TrialPlan": "你们有试用计划吗?", + "TrialPlanExplanation": "ABP商业团队许可证有14天的试用期。若要了解更多信息,请访问这里。此外,我们为团队许可证提供30天的金额返还保证。你只需要在30天内请求退款。商业和企业许可证将提供60%的金额返还保证。这是因为商业和企业许可证包含了所有模块和主题的全部源代码。", "DoYouAcceptBankWireTransfer": "你们接受银行电汇吗?", "DoYouAcceptBankWireTransferExplanation": "是的,我们接受银行电汇。
在通过银行转账发送许可费后,将您的收据和所需的许可类型通过电子邮件发送至accounting@abp.io。 我们的国际银行账户信息:", "HowToUpgrade": "可用新版本时如何升级现有应用程序?", @@ -365,7 +374,9 @@ "CompanySize": "公司规模", "Next": "下一个", "StartTrial": "开始我的免费试用", + "ContactUsQuestions": "如果你有任何问题,请联系我们", "TrialActivatedWarning": "亲爱的{0},用户只能享受 1 个免费试用期。您已经使用了试用期。", + "ActivationRequirement": "你已经距离开始你的试用还有最后一步。
检查你的信息后,我们将激活你的许可证。一旦你的许可证激活,我们将向{0}发送电子邮件。请不要担心,这个过程不会太久!", "SaveAndDownload": "保存和下载", "CompanyNameValidationMessage": "公司名称太长!", "AddressValidationMessage": "地址太长!", @@ -389,6 +400,7 @@ "UserDeveloperDescription": "“开发人员”可以在 ABP 商业版项目中编写代码,下载 ABP 示例项目,并在支持的网站上进行提问。 然而另一方面,“开发者”无法管理这个组织。", "RemoveCurrentUserFromOrganizationWarningMessage": "您正在将自己从自己的组织中移除。 您将无法再管理此组织,您确定吗?", "RenewExistingOrganizationOrCreateNewOneMessage": "您可以通过单击下面的 \"立即延长\"按钮来更新您组织的许可证,因此您可以将许可证到期日期延长 1 年。 如果您继续结帐,您将拥有一个新的组织。 您想继续开始新的组织许可吗?", + "PurchaseTrialOrganizationOrCreateNewOneMessage": "你有试用许可证。如果你想购买试用许可证,请点击“立即购买”按钮。如果你继续支付,你将会有一个新的组织。你想继续使用一个新的组织吗?", "ExtendNow": "立即延长", "CreateNewOrganization": "建立新的组织", "RenewLicenseEarly": "如果我提前更新我的许可证,我会得到一整年吗?", @@ -524,6 +536,7 @@ "Pricing_Page_Testimonial_2": "我们看到了使用 ABP Commercial 能减少定制开发项目开销的价值。 并且团队能够在不同的项目流中统一代码模式。 我们在框架中看到了能比以前更快地构建新功能的更多潜力。 我们相信我们将会持续地看到使用 ABP Commercial 的价值。", "Pricing_Page_Testimonial_3": "我们大爱 ABP。 我们不必从头开始编写所有内容。 我们从\"开箱即用\"的功能开始,只需关注我们真正需要编写的内容。 此外,ABP 架构良好,代码质量高,错误少。 如果我们需要自己来编写所需的一切,我们可能需要花费数年时间。 另一点让我们喜欢的是新版本、问题修复或改进每隔一周很快地就会出现。 我们不会等太久。", "Pricing_Page_Testimonial_4": "ABP 商业版 是一款很值得推荐的出色产品。 是在一个可配置的平台上为我们的客户推向市场的商业产品。 其框架和工具为任何团队提供的快速启动值得每一分钱。 ABP 商业版 最适合我们的需求。", + "Pricing_Page_Testimonial_5": "ABP Framework 不仅是一个框架,它还是项目开发/管理的指南,因为它提供了 DDD、GenericRepository、DI、微服务和模块化培训。 即使你不打算使用框架本身,你也可以通过 docs.abp.io 进行自己的开发,该文档已经做好了专业的准备(OpenIddict、Redis、Quartz 等)。 因为很多东西都是预先构建的,它大大缩短了项目开发时间(例如登录页面、异常处理、数据过滤、种子、审计日志、本地化、自动 API 控制器等)。 作为我们应用程序的一个示例,我使用本地事件总线进行库存控制。 因此我可以通过编写库存处理程序来管理订单移动。 不为 CreationTime,CreatorId 浪费时间真是太好了。 它们正在自动填充。", "AbpBookDownloadArea_ClaimYourEBook": "领取您的掌握ABP框架电子书", "AddMemberModal_Warning_1": "如果您尝试添加的用户名在系统中不存在,请让您的团队成员在 {0} 并与您分享他/她帐户的用户名。", "MyOrganizations_Detail_WelcomeMessage": "欢迎加入您的组织,{0}", @@ -591,6 +604,9 @@ "TrainingDetailsHeaderInfo_TrainingHour": "{0} 小时", "Trainings_Content": "培训内容", "Trial_Page_StartYourFreeTrial": "开始您的免费试用", + "TrialLicenseFeatures": "你将能够享受所有 ABP 商业特性", + "TrialPeriodDays": "你将有 {0} 天的团队许可证", + "TrialForumSupportIncident": "你将有 {0} 个论坛支持事件", "Contact_Page_Title": "联系 ABP 开发团队", "Contact_Page_Description": "如果您需要任何帮助或分享您的想法和意见,请与 ABP 开发团队联系! ABP 支持团队随时准备提供帮助。", "Demo_Page_Title": "创建演示", @@ -712,6 +728,13 @@ "Landing_Page_PaymentModuleDescription_1": "为不同的支付网关提供集成。", "Landing_Page_PaymentModuleDescription_2": "该模块提供支付网关的集成,因此您可以轻松地从客户那里获得付款。", "Landing_Page_PaymentModuleDescription_3": "该模块支持以下支付网关", - "Welcome_Page_UseSameCredentialForCommercialWebsites": "commercial.abp.io 和 support.abp.io使用相同的凭据。" + "Welcome_Page_UseSameCredentialForCommercialWebsites": "commercial.abp.io 和 support.abp.io使用相同的凭据。", + "WatchCrudPagesVideo": "观看“创建 CRUD 页面的 ABP Suite”视频!", + "WatchGeneratingFromDatabaseVideo": "观看”ABP Suite:从现有数据库表生成 CRUD 页面”视频!", + "WatchTakeCloserLookVideo": "观看“详细了解ABP Suite 的代码生成”视频!", + "ConfirmedEmailAddressRequiredToStartTrial": "你应该有一个确认的电子邮件地址,以便开始试用许可证。", + "EmailVerificationMailNotSent": "电子邮件验证邮件不能发送。", + "GetConfirmationEmail": "点击这里获取确认邮件 如果你还没有收到。", + "WhichLicenseTypeYouAreInterestedIn": "你感兴趣的许可证类型是什么?" } -} +} \ No newline at end of file diff --git a/build/common.ps1 b/build/common.ps1 index 01a7565fba..61d9cf03d2 100644 --- a/build/common.ps1 +++ b/build/common.ps1 @@ -20,8 +20,7 @@ $solutionPaths = @( "../modules/background-jobs", "../modules/account", "../modules/cms-kit", - "../modules/blob-storing-database", - "../studio" + "../modules/blob-storing-database" ) if ($full -eq "-f") diff --git a/docs/en/Distributed-Locking.md b/docs/en/Distributed-Locking.md index d29b60ad04..a1e653a6a6 100644 --- a/docs/en/Distributed-Locking.md +++ b/docs/en/Distributed-Locking.md @@ -101,6 +101,25 @@ namespace AbpDemo * `timeout` (`TimeSpan`): A timeout value to wait to obtain the lock. Default value is `TimeSpan.Zero`, which means it doesn't wait if the lock is already owned by another application. * `cancellationToken`: A cancellation token that can be triggered later to cancel the operation. +### Configuration + +#### AbpDistributedLockOptions + +`AbpDistributedLockOptions` is the main options class to configure the distributed locking. + +**Example: Set the distributed lock key prefix for the application** + +Configure(options => +{ + options.KeyPrefix = "MyApp1"; +}); + +> Write that code inside the `ConfigureServices` method of your [module class](Module-Development-Basics.md). + +##### Available Options + +* KeyPrefix (string, default: null): Specify the lock name prefix. + ### Using DistributedLock Library's API ABP's `IAbpDistributedLock` service is very limited and mainly designed to be internally used by the ABP Framework. For your own applications, you can use the DistributedLock library's own API. See its [own documentation](https://github.com/madelson/DistributedLock) for details. diff --git a/docs/en/Themes/LeptonXLite/AspNetCore.md b/docs/en/Themes/LeptonXLite/AspNetCore.md index eeaf55f545..f480141120 100644 --- a/docs/en/Themes/LeptonXLite/AspNetCore.md +++ b/docs/en/Themes/LeptonXLite/AspNetCore.md @@ -9,22 +9,22 @@ LeptonX Lite has implementation for the ABP Framework Razor Pages. It's a simpli This theme is **already installed** when you create a new solution using the startup templates. If you are using any other template, you can install this theme by following the steps below: -- Add **Volo.Abp.AspNetCore.Mvc.UI.Theme.LeptonXLite** package to your **Web** application. +- Add the **Volo.Abp.AspNetCore.Mvc.UI.Theme.LeptonXLite** package to your **Web** application. ```bash dotnet add package Volo.Abp.AspNetCore.Mvc.UI.Theme.LeptonXLite --prerelease ``` -- Remove **Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic** reference from the project since it's not necessary after switching to LeptonX Lite. +- Remove the **Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic** reference from the project since it's not necessary after switching to LeptonX Lite. - Make sure the old theme is removed and LeptonX is added in your Module class. ```diff [DependsOn( - // Remove BasicTheme module from DependsOn attribute + // Remove the BasicTheme module from DependsOn attribute - typeof(AbpAspNetCoreMvcUiBasicThemeModule), - // Add LeptonX Lite module to DependsOn attribute + // Add the LeptonX Lite module to DependsOn attribute + typeof(AbpAspNetCoreMvcUiLeptonXLiteThemeModule), )] ``` @@ -35,9 +35,9 @@ dotnet add package Volo.Abp.AspNetCore.Mvc.UI.Theme.LeptonXLite --prerelease Configure(options => { options.StyleBundles.Configure( - // Remove following line + // Remove the following line - BasicThemeBundles.Styles.Global, - // Add following line instead + // Add the following line instead + LeptonXLiteThemeBundles.Styles.Global bundle => { @@ -47,10 +47,24 @@ Configure(options => }); ``` ---- - ## Customization +### Layouts + +LeptonX Lite Mvc provides **layouts** for your **user interface** based [ABP Framework Theming](https://docs.abp.io/en/abp/latest/UI/AspNetCore/Theming). You can use **layouts** to **organize your user interface**. + +The main responsibility of a theme is to **provide** the layouts. There are **three pre-defined layouts that must be implemented by all the themes:** + +* **Application:** The **default** layout which is used by the **main** application pages. + +* **Account:** Mostly used by the **account module** for **login**, **register**, **forgot password**... pages. + +* **Empty:** The **Minimal** layout that **has no layout components** at all. + +**Layout names** are **constants** defined in the `LeptonXLiteTheme` class in the **Mvc** project **root**. + +> The layout pages define under the `Themes/LeptonXLite/Layouts` folder and you can **override it** by creating a file with the **same name** and **under** the **same folder**. + ### Toolbars LeptonX Lite includes separeted toolbars for desktop & mobile. You can manage toolbars independently. Toolbar names can be accessible in the **LeptonXLiteToolbars** class. @@ -74,3 +88,128 @@ public class MyProjectNameMainToolbarContributor : IToolbarContributor } } ``` +# LeptonX Lite Mvc Components + +Abp **helps** you make **highly customizable UI**. You can easily **customize** your themes to fit your needs. **The Virtual File System** makes it possible to **manage files** that **do not physically** exist on the **file system** (disk). It's mainly used to embed **(js, css, image..)** files into assemblies and **use them like** physical files at runtime. An application (or another module) can **override** a **virtual file of a module** just like placing a file with the **same name** and **extension** into the **same folder** of the **virtual file**. + +LeptonX Lite is built on the [Abp Framework](https://abp.io/), so you can **easily** customize your Asp.Net Core Mvc user interface by following [Abp Mvc UI Customization](https://docs.abp.io/en/abp/latest/UI/AspNetCore/Customization-xUser-Interface). + +## Brand Component + +The **brand component** is a simple component that can be used to display your brand. It contains a **logo** and a **company name**. + +![Brand component](../../images/leptonxlite-brand-component.png) + +### How to override the Brand Component in LeptonX Lite Mvc + +* The **brand component page (.cshtml file)** is defined in the `Themes/LeptonXLite/Components/Brand/Default.cshtml` file and you can **override it** by creating a file with the **same name** and **under** the **same folder**. + +* The **brand component (C# file)** is defined in the `Themes/LeptonXLite/Components/Brand/MainNavbarBrandViewComponent.cs` file and you can **override it** by creating a file with the **same name** and under the **same folder**. + +## Breadcrumb Component + +On websites that have a lot of pages, **breadcrumb navigation** can greatly **enhance the way users find their way** around. In terms of **usability**, breadcrumbs reduce the number of actions a website **visitor** needs to take in order to get to a **higher-level page**, and they **improve** the **findability** of **website sections** and **pages**. + +![Breadcrumb component](../../images/leptonxlite-breadcrumb-component.png) + +### How to override the Breadcrumb Component in LeptonX Lite Mvc + +* The **breadcrumb component page (.cshtml file)** is defined in the `Themes/LeptonXLite/Components/Breadcrumbs/Default.cshtml` file and you can **override it** by creating a file with the **same name** and **under** the **same folder**. + +* The **breadcrumb component (C# file)** is defined in the `Themes/LeptonXLite/Components/Breadcrumbs/BreadcrumbsViewComponent.cs` file and you can **override it** by creating a file with the **same name** and **under** the **same folder**. + +## Sidebar Menu Component + +Sidebar menus have been used as **a directory for Related Pages** to a **Service** offering, **Navigation** items to a **specific service** or topic and even just as **Links** the user may be interested in. + +![Sidebar menu component](../../images/leptonxlite-sidebar-menu-component.png) + +### How to override the Sidebar Menu Component in LeptonX Lite Mvc + +* **Sidebar menu page (.cshtml)** is defined in the `Themes/LeptonXLite/Components/Menu/Default.cshtml` file and you can **override it** by creating a file with the **same name** and **under** the **same folder**. + +* If you want to **override the menu component (C#)** you can override the `Themes/LeptonXLite/Components/Menu/MainMenuViewComponent.cs` file and you can **override it** by creating a file with the **same name** and **under** the **same folder**. + +> The **sidebar menu** renders menu items **dynamically**. The **menu item** is a **partial view** and is defined in the `Themes/LeptonXLite/Components/Menu/_MenuItem.cshtml` file and you can **override it** by creating a file with the **same name** and **under** the **same folder**. + +## Page Alerts Component + +Provides contextual **feedback messages** for typical user actions with the handful of **available** and **flexible** **alert messages**. Alerts are available for any length of text, as well as an **optional dismiss button**. + +![Page alerts component](../../images/leptonxlite-page-alerts-component.png) + +### How to override the Page Alerts Component in LeptonX Lite Mvc + +* The **page alerts component page (.cshtml file)** is defined in the `Themes/LeptonXLite/Components/PageAlerts/Default.cshtml` file and you can **override it** by creating a file with the **same name** and **under** the **same folder**. + +* The **page alerts component (C#)** is defined in the `Themes/LeptonXLite/Components/PageAlerts/PageAlertsViewComponent.cs` file and you can **override it** by creating a file with the **same name** and **under** the **same folder**. + +## Toolbar Component + +Toolbar items are used to add **extra functionality to the toolbar**. The toolbar is a **horizontal bar** that **contains** a group of **toolbar items**. + +### How to override the Toolbar Component in LeptonX Lite Mvc + +* The **toolbar component page (.cshtml file)** is defined in the `Themes/LeptonXLite/Components/Toolbar/Default.cshtml` file and you can **override it** by creating a file with the **same name** and **under** the **same folder**. + +* The **toolbar component (C#)** is defined in the `Themes/LeptonXLite/Components/Toolbar/ToolbarViewComponent.cs` file and you can **override it** by creating a file with the **same name** and **under** the **same folder**. + +## Toolbar Item Component + +The toolbar item is a **single item** that **contains** a **link**, an **icon**, a **label** etc.. + +### How to override the Toolbar Item Component in LeptonX Lite Mvc + +* The **toolbar item component page (.cshtml file)** is defined in the `Themes/LeptonXLite/Components/ToolbarItems/Default.cshtml` file and you can **override it** by creating a file with the **same name** and **under** the **same folder**. + +* The **toolbar item component (C#)** is defined in the `Themes/LeptonXLite/Components/ToolbarItems/ToolbarItemsViewComponent.cs` file and you can **override it** by creating a file with the **same name** and **under** the **same folder**. + +You can find the toolbar components below: + +## Language Switch Component + +Think about a **multi-lingual** website and the first thing that could **hit your mind** is **the language switch component**. A **navigation bar** is a **great place** to **embed a language switch**. By embedding the language switch in the navigation bar of your website, you would **make it simpler** for users to **find it** and **easily** switch the **language** **without trying to locate it across the website.** + +![Language switch component](../../images/leptonxlite-language-switch-component.png) + +### How to override the Language Switch Component in LeptonX Lite Mvc + +* The **language switch component page (.cshtml file)** is defined in the `Themes/LeptonXLite/Components/LanguageSwitch/Default.cshtml` file and you can **override it** by creating a file with the **same name** and **under** the **same folder**. + +* The **language switch component (C#)** is defined in the `Themes/LeptonXLite/Components/LanguageSwitch/LanguageSwitchViewComponent.cs` file and you can **override it** by creating a file with the **same name** and **under** the **same folder**. + +## Mobile Language Switch Component + +The **mobile** **language switch component** is used to switch the language of the website **on mobile devices**. The mobile language switch component is a **dropdown menu** that **contains all the languages** of the website. + +![Mobil language switch component](../../images/leptonxlite-mobile-language-switch-component.png) + +### How to override the Mobile Language Switch Component in LeptonX Lite Mvc + +* The **mobile language switch component page (.cshtml file)** is defined in the `Themes/LeptonXLite/Components/MobileLanguageSwitch/Default.cshtml` file and you can **override it** by creating a file with the **same name** and **under** the **same folder**. + +* The **mobile language switch component (C#)** is defined in the `Themes/LeptonXLite/Components/MobileLanguageSwitch/MobileLanguageSwitchViewComponent.cs` file and you can **override it** by creating a file with the **same name** and **under** the **same folder**. + +## User Menu Component + +The **User Menu** is the **menu** that **drops down** when you **click your name** or **profile picture** in the **upper right corner** of your page (**in the toolbar**). It drops down options such as **Settings**, **Logout**, etc. + +![User menu component](../../images/leptonxlite-user-menu-component.png) + +### How to override the User Menu Component in LeptonX Lite Mvc + +* The **user menu component page (.cshtml file)** is defined in the `Themes/LeptonXLite/Components/UserMenu/Default.cshtml` file and you can **override it** by creating a file with the **same name** and **under** the **same folder**. + +* The **user menu component (C#)** is defined in the `Themes/LeptonXLite/Components/UserMenu/UserMenuViewComponent.cs` file and you can **override it** by creating a file with the **same name** and **under** the **same folder**. + +## Mobile User Menu Component + +The **mobile user menu component** is used to display the **user menu on mobile devices**. The mobile user menu component is a **dropdown menu** that contains all the **options** of the **user menu**. + +![Mobile user menu component](../../images/leptonxlite-mobile-user-menu-component.png) + +### How to override the Mobile User Menu Component in LeptonX Lite Mvc + +* The **mobile user menu component page (.cshtml file)** is defined in the `Themes/LeptonXLite/Components/MobileUserMenu/Default.cshtml` file and you can **override it** by creating a file with the **same name** and **under** the **same folder**. + +* The **mobile user menu component (C#)** is defined in the `Themes/LeptonLite/Components/MobileUserMenu/MobileUserMenuViewComponent.cs` file and you can **override it** by creating a file with the **same name** and **under** the **same folder**. diff --git a/docs/en/UI/Blazor/Layout-Hooks.md b/docs/en/UI/Blazor/Layout-Hooks.md new file mode 100644 index 0000000000..1118e02d37 --- /dev/null +++ b/docs/en/UI/Blazor/Layout-Hooks.md @@ -0,0 +1,125 @@ +# Blazor UI: Layout Hooks + +ABP Framework theming system places the page layout into the [theme](Theming.md) NuGet packages. That means the final application doesn't include a layout, so you can't directly change the layout code to customize it. + +> If you create a Blazor WASM project, the `index.html` file will be included within the template. You can also customize it to your needs. + +You can copy the theme code into your solution. In this case, you are completely free to customize it. However, then you won't be able to get automatic updates of the theme (by upgrading the theme NuGet package). + +The **Layout Hook System** allows you to **add code** at some specific parts of the layout. All layouts of all themes should implement these hooks. Finally, you can add a **razor component** into a hook point. + +## Example: Add a Simple Announcement Alert + +Assume that you need to add a simple banner to the layout (that will be available for all the pages) to make an announcement about your new product. First, **create a razor component** in your project: + +![bookstore-banner-component](../../images/bookstore-banner-component.png) + +**AnnouncementComponent.razor.cs** + +```csharp +using System.Threading.Tasks; +using Microsoft.AspNetCore.Components; +using Microsoft.JSInterop; + +namespace Acme.BookStore.Blazor.Components; + +public partial class AnnouncementComponent : ComponentBase +{ + private const string AnnouncementLocalStorageKey = "product-announcement-status"; + + [Inject] + public IJSRuntime JsRuntime { get; set; } + + public bool ShowBanner { get; set; } + + protected override async Task OnInitializedAsync() + { + ShowBanner = await ShowAnnouncementBannerAsync(); + } + + private async Task ShowAnnouncementBannerAsync() + { + var announcementLocalStorageValue = await JsRuntime.InvokeAsync("localStorage.getItem", AnnouncementLocalStorageKey); + + return announcementLocalStorageValue != null && + bool.TryParse(announcementLocalStorageValue, out var showAnnouncementBanner) && showAnnouncementBanner; + } + + private async Task HideAnnouncementBannerAsync() + { + await JsRuntime.InvokeVoidAsync("localStorage.setItem", AnnouncementLocalStorageKey, true); + ShowBanner = false; + StateHasChanged(); + } +} +``` + +**AnnouncementComponent.razor** + +```html +@if(ShowBanner) +{ +
+ A brand new product is in sale. Click here to learn more. + +
+} +``` + +Then, you can add this component to any of the hook points in the `ConfigureServices` of your module class: + +```csharp +Configure(options => +{ + options.Add( + LayoutHooks.Body.Last, //The hook name + typeof(AnnouncementComponent) //The component to add + ); +}); +``` + +Now, the `AnnouncementComponent` will be rendered in the `body` of the page as the last item. + +### Specifying the Layout + +The configuration above adds the `AnnouncementComponent` to all layouts. You may want to only add it to a specific layout: + +````csharp +Configure(options => +{ + options.Add( + LayoutHooks.Body.Last, + typeof(AnnouncementComponent), + layout: StandardLayouts.Application //Set the layout to add + ); +}); +```` + +See the *Layouts* section below to learn more about the layout system. + +## Layout Hook Points + +There are some pre-defined layout hook points. The standard hook points are: + +* `LayoutHooks.Body.First`: Used to add a component as the first item in the HTML body tag. +* `LayoutHooks.Body.Last`: Used to add a component as the last item in the HTML body tag. + +> You (or the modules you are using) can add **multiple items to the same hook point**. All of them will be added to the layout in the order they were added. + +## Layouts + +The layout system allows themes to define the standard named layouts and allows any page to select a proper layout for its purpose. There is one pre-defined layout: + +* "**Application**": The main (and the default) layout for an application. It typically contains a header, menu (sidebar), footer, toolbar... etc. + +This layout is defined in the `StandardLayouts` class as constants. You can definitely create your own layouts, but this layout is the standard layout and it's implemented by all the themes out of the box. + +> If you don't specify the layout, your razor component will be rendered in all of the layouts. + +### Layout Location + +You can find the `MainLayout.razor` [here](https://github.com/abpframework/abp/blob/dev/modules/basic-theme/src/Volo.Abp.AspNetCore.Components.Web.BasicTheme/Themes/Basic/MainLayout.razor) for the basic theme. You can take it as a reference to build your own layouts or you can override it, if necessary. + +## See Also + +* [Customization / Overriding Components](Customization-Overriding-Components.md) diff --git a/docs/en/docs-nav.json b/docs/en/docs-nav.json index 14c584d376..035f150705 100644 --- a/docs/en/docs-nav.json +++ b/docs/en/docs-nav.json @@ -939,6 +939,10 @@ { "text": "PWA Configuration", "path": "UI/Blazor/Pwa-Configuration.md" + }, + { + "text": "Layout Hooks", + "path": "UI/Blazor/Layout-Hooks.md" } ] }, diff --git a/docs/en/images/bookstore-banner-component.png b/docs/en/images/bookstore-banner-component.png new file mode 100644 index 0000000000..2363b06fae Binary files /dev/null and b/docs/en/images/bookstore-banner-component.png differ diff --git a/docs/en/images/leptonxlite-brand-component.png b/docs/en/images/leptonxlite-brand-component.png new file mode 100644 index 0000000000..c06a51612f Binary files /dev/null and b/docs/en/images/leptonxlite-brand-component.png differ diff --git a/docs/en/images/leptonxlite-breadcrumb-component.png b/docs/en/images/leptonxlite-breadcrumb-component.png new file mode 100644 index 0000000000..9026ca4c52 Binary files /dev/null and b/docs/en/images/leptonxlite-breadcrumb-component.png differ diff --git a/docs/en/images/leptonxlite-language-switch-component.png b/docs/en/images/leptonxlite-language-switch-component.png new file mode 100644 index 0000000000..027910c23b Binary files /dev/null and b/docs/en/images/leptonxlite-language-switch-component.png differ diff --git a/docs/en/images/leptonxlite-mobile-language-switch-component.png b/docs/en/images/leptonxlite-mobile-language-switch-component.png new file mode 100644 index 0000000000..a058820743 Binary files /dev/null and b/docs/en/images/leptonxlite-mobile-language-switch-component.png differ diff --git a/docs/en/images/leptonxlite-mobile-user-menu-component.png b/docs/en/images/leptonxlite-mobile-user-menu-component.png new file mode 100644 index 0000000000..1a51c341d7 Binary files /dev/null and b/docs/en/images/leptonxlite-mobile-user-menu-component.png differ diff --git a/docs/en/images/leptonxlite-page-alerts-component.png b/docs/en/images/leptonxlite-page-alerts-component.png new file mode 100644 index 0000000000..7976412fb2 Binary files /dev/null and b/docs/en/images/leptonxlite-page-alerts-component.png differ diff --git a/docs/en/images/leptonxlite-sidebar-menu-component.png b/docs/en/images/leptonxlite-sidebar-menu-component.png new file mode 100644 index 0000000000..6afe4029e8 Binary files /dev/null and b/docs/en/images/leptonxlite-sidebar-menu-component.png differ diff --git a/docs/en/images/leptonxlite-user-menu-component.png b/docs/en/images/leptonxlite-user-menu-component.png new file mode 100644 index 0000000000..a0039e996c Binary files /dev/null and b/docs/en/images/leptonxlite-user-menu-component.png differ diff --git a/docs/zh-Hans/Distributed-Locking.md b/docs/zh-Hans/Distributed-Locking.md index 2176230403..a570f598af 100644 --- a/docs/zh-Hans/Distributed-Locking.md +++ b/docs/zh-Hans/Distributed-Locking.md @@ -101,6 +101,25 @@ namespace AbpDemo * `timeout` (`TimeSpan`): 等待获取锁的超时值. 默认值为`TimeSpan.Zero`, 这意味着如果锁已经被另一个应用程序拥有, 它不会等待. * `cancellationToken`: 取消令牌可在触发后取消操作. +### 配置 + +#### AbpDistributedLockOptions + +`AbpDistributedLockOptions` 是配置分布式锁的主要选项类. + +**示例: 设置应用程序的分布式锁Key前缀** + +Configure(options => +{ + options.KeyPrefix = "MyApp1"; +}); + +> 在你的[模块类](Module-Development-Basics.md)中的 `ConfigureServices` 方法进行配置. + +##### 可用选项 + +* KeyPrefix (string, 默认值: null): 指定分布式锁名称前缀. + ### 使用DistributedLock库的API ABP的`IAbpDistributedLock`服务非常有限, 主要用于ABP框架的内部使用. 对于你自己的应用程序, 可以使用DistributedLock库自己的API. 参见[文档](https://github.com/madelson/DistributedLock)详细信息. diff --git a/framework/src/Volo.Abp.Auditing/Volo/Abp/Auditing/EntityPropertyChangeInfo.cs b/framework/src/Volo.Abp.Auditing/Volo/Abp/Auditing/EntityPropertyChangeInfo.cs index f6e1b76cd7..5e92f6622e 100644 --- a/framework/src/Volo.Abp.Auditing/Volo/Abp/Auditing/EntityPropertyChangeInfo.cs +++ b/framework/src/Volo.Abp.Auditing/Volo/Abp/Auditing/EntityPropertyChangeInfo.cs @@ -9,19 +9,19 @@ public class EntityPropertyChangeInfo /// Maximum length of property. /// Value: 96. /// - public const int MaxPropertyNameLength = 96; + public static int MaxPropertyNameLength = 96; /// /// Maximum length of and properties. /// Value: 512. /// - public const int MaxValueLength = 512; + public static int MaxValueLength = 512; /// /// Maximum length of property. /// Value: 512. /// - public const int MaxPropertyTypeFullNameLength = 192; + public static int MaxPropertyTypeFullNameLength = 192; public virtual string NewValue { get; set; } diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/AbpIoSourceCodeStore.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/AbpIoSourceCodeStore.cs index 10c65d95e5..6f013272c3 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/AbpIoSourceCodeStore.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/AbpIoSourceCodeStore.cs @@ -221,7 +221,9 @@ public class AbpIoSourceCodeStore : ISourceCodeStore, ITransientDependency } catch (Exception ex) { - throw new Exception($"Error occured while getting the versions from {url} : {ex.Message}"); + Logger.LogWarning($"Error occured while getting the versions from {url} : {ex.Message}"); + // The remote service is currently unavailable, try to work offline. + return true; } } diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/ChangeThemeStep.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/ChangeThemeStep.cs index 33ecad0719..f3b0fed914 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/ChangeThemeStep.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/ChangeThemeStep.cs @@ -61,7 +61,7 @@ public class ChangeThemeStep : ProjectBuildPipelineStep ChangeNamespace( context, "/MyCompanyName.MyProjectName.Blazor/MyProjectNameBlazorModule.cs", - $"Volo.Abp.AspNetCore.Components.Web.{defaultThemeName}Theme.Themes.{defaultThemeName}", + $"Volo.Abp.AspNetCore.Components.Web.{defaultThemeName}Theme.Components", "Volo.Abp.AspNetCore.Components.Web.BasicTheme.Themes.Basic" ); @@ -69,7 +69,7 @@ public class ChangeThemeStep : ProjectBuildPipelineStep #region Blazor.Server Projects - ChangeThemeToBasicForBlazorServerProjects(context, defaultThemeName); + ChangeThemeToBasicForBlazorProjects(context, defaultThemeName); #endregion @@ -105,6 +105,24 @@ public class ChangeThemeStep : ProjectBuildPipelineStep "node_modules/bootstrap-icons/font/bootstrap-icons.css" ); + if(defaultThemeName == "LeptonX") + { + ReplaceMethodNames( + context, + "/angular/src/app/app.module.ts", + "HttpErrorComponent, ", + "" + ); + + ChangeModuleImportBetweenStatements( + context, + "/angular/src/app/app.module.ts", + "ThemeSharedModule.forRoot", + "AccountAdminConfigModule.forRoot", + "ThemeSharedModule.forRoot()," + ); + } + #endregion } @@ -510,6 +528,41 @@ public class ChangeThemeStep : ProjectBuildPipelineStep file.SetLines(lines.Where(x => x != null)); } + private void ChangeModuleImportBetweenStatements( + ProjectBuildContext context, + string filePath, + string firstStatement, + string lastStatement, + string newStatement) + { + var file = context.Files.FirstOrDefault(x => x.Name.Contains(filePath)); + if (file == null) + { + return; + } + + file.NormalizeLineEndings(); + + var lines = file.GetLines(); + var firstLineIndex = lines.FindIndex(line => line.Contains(firstStatement)); + var lastLineIndex = lines.FindIndex(line => line.Contains(lastStatement)); + + if(firstLineIndex == -1 || lastLineIndex == -1) + { + return; + } + + lines[firstLineIndex] = newStatement; + + for (var i = firstLineIndex + 1; i <= lastLineIndex; i++) + { + lines[i] = null; + } + + + file.SetLines(lines.Where(x => x != null)); + } + protected void ReplaceMethodNames( ProjectBuildContext context, string filePath, @@ -668,7 +721,7 @@ public class ChangeThemeStep : ProjectBuildPipelineStep } } - private void ChangeThemeToBasicForBlazorServerProjects(ProjectBuildContext context, string defaultThemeName) + private void ChangeThemeToBasicForBlazorProjects(ProjectBuildContext context, string defaultThemeName) { var projects = new Dictionary { @@ -733,7 +786,7 @@ public class ChangeThemeStep : ProjectBuildPipelineStep ChangeNamespaceAndKeyword( context, $"/MyCompanyName.MyProjectName.{project.Key}/Pages/_Host.cshtml", - $"Volo.Abp.AspNetCore.Components.Web.{defaultThemeName}Theme.Themes.{defaultThemeName}", + $"Volo.Abp.AspNetCore.Components.Web.{defaultThemeName}Theme.Components", "Volo.Abp.AspNetCore.Components.Web.BasicTheme.Themes.Basic", $"Blazor{defaultThemeName}ThemeBundles.Styles.Global", "BlazorBasicThemeBundles.Styles.Global" diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/RemoveDependencyFromPackageJsonFileStep.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/RemoveDependencyFromPackageJsonFileStep.cs index 3eabb6621e..bff28d703b 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/RemoveDependencyFromPackageJsonFileStep.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/RemoveDependencyFromPackageJsonFileStep.cs @@ -17,8 +17,7 @@ public class RemoveDependencyFromPackageJsonFileStep : ProjectBuildPipelineStep public override void Execute(ProjectBuildContext context) { - var packageJsonFile = context.Files.FirstOrDefault(f => f.Name.Contains(_packageJsonFilePath)); - + var packageJsonFile = context.Files.FirstOrDefault(f => f.Name.Contains(_packageJsonFilePath) && !f.Name.Contains("node_modules")); if (packageJsonFile == null) { return; diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Templates/App/AppTemplateBase.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Templates/App/AppTemplateBase.cs index 16bea2740f..22d33be136 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Templates/App/AppTemplateBase.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Templates/App/AppTemplateBase.cs @@ -210,7 +210,7 @@ public abstract class AppTemplateBase : TemplateInfo } steps.Add(new ChangeThemeStep()); - RemoveLeptonXThemePackagesFromPackageJsonFiles(steps, isProTemplate: IsPro()); + RemoveLeptonXThemePackagesFromPackageJsonFiles(steps, isProTemplate: IsPro(), uiFramework: context.BuildArgs.UiFramework); } private static bool IsDefaultThemeForTemplate(Theme theme) @@ -224,50 +224,55 @@ public abstract class AppTemplateBase : TemplateInfo return defaultThemesForTemplates.Any(defaultTheme => defaultTheme == theme); } - private static void RemoveLeptonXThemePackagesFromPackageJsonFiles(List steps, bool isProTemplate) + private static void RemoveLeptonXThemePackagesFromPackageJsonFiles(List steps, bool isProTemplate, UiFramework uiFramework) { + var mvcUiPackageName = isProTemplate ? "@volo/abp.aspnetcore.mvc.ui.theme.leptonx" : "@abp/aspnetcore.mvc.ui.theme.leptonxlite"; var packageJsonFilePaths = new List { "/MyCompanyName.MyProjectName.Web/package.json", "/MyCompanyName.MyProjectName.Web.Host/package.json", "/MyCompanyName.MyProjectName.HttpApi.HostWithIds/package.json", + "/MyCompanyName.MyProjectName.HttpApi.Host/package.json", "/MyCompanyName.MyProjectName.AuthServer/package.json", "/MyCompanyName.MyProjectName/package.json", "/MyCompanyName.MyProjectName.Host/package.json", "/MyCompanyName.MyProjectName.Host.Mongo/package.json" }; - - var blazorServerPackageJsonFilePaths = new List - { - "/MyCompanyName.MyProjectName.Blazor.Server/package.json", - "/MyCompanyName.MyProjectName.Blazor.Server.Tiered/package.json", - "/MyCompanyName.MyProjectName.Blazor.Server.Mongo/package.json" - }; - - var angularPackageJsonFilePaths = new List - { - "/angular/package.json" - }; - - var mvcUiPackageName = isProTemplate ? "@volo/abp.aspnetcore.mvc.ui.theme.leptonx" : "@abp/aspnetcore.mvc.ui.theme.leptonxlite"; - var blazorServerUiPackageName = isProTemplate ? "@volo/aspnetcore.components.server.leptonxtheme" : "@abp/aspnetcore.components.server.leptonxlitetheme"; - var ngUiPackageName = isProTemplate ? "@volosoft/abp.ng.theme.lepton-x" : "@abp/ng.theme.lepton-x"; foreach (var packageJsonFilePath in packageJsonFilePaths) { steps.Add(new RemoveDependencyFromPackageJsonFileStep(packageJsonFilePath, mvcUiPackageName)); } - foreach (var blazorServerPackageJsonFilePath in blazorServerPackageJsonFilePaths) + if (uiFramework == UiFramework.BlazorServer) { - steps.Add(new RemoveDependencyFromPackageJsonFileStep(blazorServerPackageJsonFilePath, mvcUiPackageName)); - steps.Add(new RemoveDependencyFromPackageJsonFileStep(blazorServerPackageJsonFilePath, blazorServerUiPackageName)); + var blazorServerUiPackageName = isProTemplate ? "@volo/aspnetcore.components.server.leptonxtheme" : "@abp/aspnetcore.components.server.leptonxlitetheme"; + var blazorServerPackageJsonFilePaths = new List + { + "/MyCompanyName.MyProjectName.Blazor/package.json", + "/MyCompanyName.MyProjectName.Blazor.Server.Tiered/package.json", + "/MyCompanyName.MyProjectName.Blazor.Server.Mongo/package.json" + }; + + foreach (var blazorServerPackageJsonFilePath in blazorServerPackageJsonFilePaths) + { + steps.Add(new RemoveDependencyFromPackageJsonFileStep(blazorServerPackageJsonFilePath, mvcUiPackageName)); + steps.Add(new RemoveDependencyFromPackageJsonFileStep(blazorServerPackageJsonFilePath, blazorServerUiPackageName)); + } } - - foreach (var angularPackageJsonFilePath in angularPackageJsonFilePaths) + else if (uiFramework == UiFramework.Angular) { - steps.Add(new RemoveDependencyFromPackageJsonFileStep(angularPackageJsonFilePath, ngUiPackageName)); - steps.Add(new RemoveDependencyFromPackageJsonFileStep(angularPackageJsonFilePath, "bootstrap-icons")); + var ngUiPackageName = isProTemplate ? "@volosoft/abp.ng.theme.lepton-x" : "@abp/ng.theme.lepton-x"; + var angularPackageJsonFilePaths = new List + { + "/angular/package.json" + }; + + foreach (var angularPackageJsonFilePath in angularPackageJsonFilePaths) + { + steps.Add(new RemoveDependencyFromPackageJsonFileStep(angularPackageJsonFilePath, ngUiPackageName)); + steps.Add(new RemoveDependencyFromPackageJsonFileStep(angularPackageJsonFilePath, "bootstrap-icons")); + } } } diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Templates/Microservice/MicroserviceTemplateBase.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Templates/Microservice/MicroserviceTemplateBase.cs index 319326f3d4..54d234b5c3 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Templates/Microservice/MicroserviceTemplateBase.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Templates/Microservice/MicroserviceTemplateBase.cs @@ -48,46 +48,50 @@ public abstract class MicroserviceTemplateBase : TemplateInfo } steps.Add(new ChangeThemeStep()); - RemoveLeptonXThemePackagesFromPackageJsonFiles(steps); + RemoveLeptonXThemePackagesFromPackageJsonFiles(steps, uiFramework: context.BuildArgs.UiFramework); } - private static void RemoveLeptonXThemePackagesFromPackageJsonFiles(List steps) + private static void RemoveLeptonXThemePackagesFromPackageJsonFiles(List steps, UiFramework uiFramework) { + var mvcUiPackageName = "@volo/abp.aspnetcore.mvc.ui.theme.leptonx"; var packageJsonFilePaths = new List { "/MyCompanyName.MyProjectName.AuthServer/package.json", "/MyCompanyName.MyProjectName.Web/package.json" }; - var blazorServerPackageJsonFilePaths = new List - { - "/MyCompanyName.MyProjectName.Blazor.Server/package.json" - }; - - var angularPackageJsonFilePaths = new List - { - "/angular/package.json" - }; - - var mvcUiPackageName = "@volo/abp.aspnetcore.mvc.ui.theme.leptonx"; - var blazorServerUiPackageName = "@volo/aspnetcore.components.server.leptonxtheme"; - var ngUiPackageName = "@volosoft/abp.ng.theme.lepton-x"; - foreach (var packageJsonFilePath in packageJsonFilePaths) { steps.Add(new RemoveDependencyFromPackageJsonFileStep(packageJsonFilePath, mvcUiPackageName)); } - foreach (var blazorServerPackageJsonFilePath in blazorServerPackageJsonFilePaths) + if (uiFramework == UiFramework.BlazorServer) { - steps.Add(new RemoveDependencyFromPackageJsonFileStep(blazorServerPackageJsonFilePath, mvcUiPackageName)); - steps.Add(new RemoveDependencyFromPackageJsonFileStep(blazorServerPackageJsonFilePath, blazorServerUiPackageName)); + var blazorServerUiPackageName = "@volo/aspnetcore.components.server.leptonxtheme"; + var blazorServerPackageJsonFilePaths = new List + { + "/MyCompanyName.MyProjectName.Blazor/package.json" + }; + + foreach (var blazorServerPackageJsonFilePath in blazorServerPackageJsonFilePaths) + { + steps.Add(new RemoveDependencyFromPackageJsonFileStep(blazorServerPackageJsonFilePath, mvcUiPackageName)); + steps.Add(new RemoveDependencyFromPackageJsonFileStep(blazorServerPackageJsonFilePath, blazorServerUiPackageName)); + } } - - foreach (var angularPackageJsonFilePath in angularPackageJsonFilePaths) + else if (uiFramework == UiFramework.Angular) { - steps.Add(new RemoveDependencyFromPackageJsonFileStep(angularPackageJsonFilePath, ngUiPackageName)); - steps.Add(new RemoveDependencyFromPackageJsonFileStep(angularPackageJsonFilePath, "bootstrap-icons")); + var ngUiPackageName = "@volosoft/abp.ng.theme.lepton-x"; + var angularPackageJsonFilePaths = new List + { + "/angular/package.json" + }; + + foreach (var angularPackageJsonFilePath in angularPackageJsonFilePaths) + { + steps.Add(new RemoveDependencyFromPackageJsonFileStep(angularPackageJsonFilePath, ngUiPackageName)); + steps.Add(new RemoveDependencyFromPackageJsonFileStep(angularPackageJsonFilePath, "bootstrap-icons")); + } } } diff --git a/framework/src/Volo.Abp.DistributedLocking.Abstractions/Volo/Abp/DistributedLocking/AbpDistributedLockOptions.cs b/framework/src/Volo.Abp.DistributedLocking.Abstractions/Volo/Abp/DistributedLocking/AbpDistributedLockOptions.cs new file mode 100644 index 0000000000..8a885ae877 --- /dev/null +++ b/framework/src/Volo.Abp.DistributedLocking.Abstractions/Volo/Abp/DistributedLocking/AbpDistributedLockOptions.cs @@ -0,0 +1,14 @@ +namespace Volo.Abp.DistributedLocking; + +public class AbpDistributedLockOptions +{ + /// + /// DistributedLock key prefix. + /// + public string KeyPrefix { get; set; } + + public AbpDistributedLockOptions() + { + KeyPrefix = ""; + } +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.DistributedLocking.Abstractions/Volo/Abp/DistributedLocking/DistributedLockKeyNormalizer.cs b/framework/src/Volo.Abp.DistributedLocking.Abstractions/Volo/Abp/DistributedLocking/DistributedLockKeyNormalizer.cs new file mode 100644 index 0000000000..bce237c5e3 --- /dev/null +++ b/framework/src/Volo.Abp.DistributedLocking.Abstractions/Volo/Abp/DistributedLocking/DistributedLockKeyNormalizer.cs @@ -0,0 +1,19 @@ +using Microsoft.Extensions.Options; +using Volo.Abp.DependencyInjection; + +namespace Volo.Abp.DistributedLocking; + +public class DistributedLockKeyNormalizer : IDistributedLockKeyNormalizer, ITransientDependency +{ + protected AbpDistributedLockOptions Options { get; } + + public DistributedLockKeyNormalizer(IOptions options) + { + Options = options.Value; + } + + public virtual string NormalizeKey(string name) + { + return $"{Options.KeyPrefix}{name}"; + } +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.DistributedLocking.Abstractions/Volo/Abp/DistributedLocking/IDistributedLockKeyNormalizer.cs b/framework/src/Volo.Abp.DistributedLocking.Abstractions/Volo/Abp/DistributedLocking/IDistributedLockKeyNormalizer.cs new file mode 100644 index 0000000000..13f30cca28 --- /dev/null +++ b/framework/src/Volo.Abp.DistributedLocking.Abstractions/Volo/Abp/DistributedLocking/IDistributedLockKeyNormalizer.cs @@ -0,0 +1,7 @@ +namespace Volo.Abp.DistributedLocking; + +public interface IDistributedLockKeyNormalizer +{ + string NormalizeKey(string name); + +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.DistributedLocking.Abstractions/Volo/Abp/DistributedLocking/LocalAbpDistributedLock.cs b/framework/src/Volo.Abp.DistributedLocking.Abstractions/Volo/Abp/DistributedLocking/LocalAbpDistributedLock.cs index 9eb7a76b9d..fdec4f1d3f 100644 --- a/framework/src/Volo.Abp.DistributedLocking.Abstractions/Volo/Abp/DistributedLocking/LocalAbpDistributedLock.cs +++ b/framework/src/Volo.Abp.DistributedLocking.Abstractions/Volo/Abp/DistributedLocking/LocalAbpDistributedLock.cs @@ -9,15 +9,22 @@ namespace Volo.Abp.DistributedLocking; public class LocalAbpDistributedLock : IAbpDistributedLock, ISingletonDependency { private readonly ConcurrentDictionary _localSyncObjects = new(); + protected IDistributedLockKeyNormalizer DistributedLockKeyNormalizer { get; } + public LocalAbpDistributedLock(IDistributedLockKeyNormalizer distributedLockKeyNormalizer) + { + DistributedLockKeyNormalizer = distributedLockKeyNormalizer; + } + public async Task TryAcquireAsync( string name, TimeSpan timeout = default, CancellationToken cancellationToken = default) { Check.NotNullOrWhiteSpace(name, nameof(name)); - - var semaphore = _localSyncObjects.GetOrAdd(name, _ => new SemaphoreSlim(1, 1)); + var key = DistributedLockKeyNormalizer.NormalizeKey(name); + + var semaphore = _localSyncObjects.GetOrAdd(key, _ => new SemaphoreSlim(1, 1)); if (!await semaphore.WaitAsync(timeout, cancellationToken)) { diff --git a/framework/src/Volo.Abp.DistributedLocking.Dapr/Volo/Abp/DistributedLocking/Dapr/DaprAbpDistributedLock.cs b/framework/src/Volo.Abp.DistributedLocking.Dapr/Volo/Abp/DistributedLocking/Dapr/DaprAbpDistributedLock.cs index 7f95a56542..b4116c105c 100644 --- a/framework/src/Volo.Abp.DistributedLocking.Dapr/Volo/Abp/DistributedLocking/Dapr/DaprAbpDistributedLock.cs +++ b/framework/src/Volo.Abp.DistributedLocking.Dapr/Volo/Abp/DistributedLocking/Dapr/DaprAbpDistributedLock.cs @@ -10,13 +10,16 @@ public class DaprAbpDistributedLock : IAbpDistributedLock, ITransientDependency protected AbpDaprClientFactory DaprClientFactory { get; } protected AbpDistributedLockDaprOptions DistributedLockDaprOptions { get; } protected AbpDaprOptions DaprOptions { get; } + protected IDistributedLockKeyNormalizer DistributedLockKeyNormalizer { get; } public DaprAbpDistributedLock( AbpDaprClientFactory daprClientFactory, IOptions distributedLockDaprOptions, - IOptions daprOptions) + IOptions daprOptions, + IDistributedLockKeyNormalizer distributedLockKeyNormalizer) { DaprClientFactory = daprClientFactory; + DistributedLockKeyNormalizer = distributedLockKeyNormalizer; DaprOptions = daprOptions.Value; DistributedLockDaprOptions = distributedLockDaprOptions.Value; } @@ -32,10 +35,11 @@ public class DaprAbpDistributedLock : IAbpDistributedLock, ITransientDependency } var daprClient = await DaprClientFactory.CreateAsync(); + var key = DistributedLockKeyNormalizer.NormalizeKey(name); var lockResponse = await daprClient.Lock( DistributedLockDaprOptions.StoreName, - name, + key, DaprOptions.AppId, (int)timeout.TotalSeconds, cancellationToken); diff --git a/framework/src/Volo.Abp.DistributedLocking/Volo/Abp/DistributedLocking/MedallionAbpDistributedLock.cs b/framework/src/Volo.Abp.DistributedLocking/Volo/Abp/DistributedLocking/MedallionAbpDistributedLock.cs index 769303a348..0defc5a75f 100644 --- a/framework/src/Volo.Abp.DistributedLocking/Volo/Abp/DistributedLocking/MedallionAbpDistributedLock.cs +++ b/framework/src/Volo.Abp.DistributedLocking/Volo/Abp/DistributedLocking/MedallionAbpDistributedLock.cs @@ -12,13 +12,17 @@ public class MedallionAbpDistributedLock : IAbpDistributedLock, ITransientDepend { protected IDistributedLockProvider DistributedLockProvider { get; } protected ICancellationTokenProvider CancellationTokenProvider { get; } + + protected IDistributedLockKeyNormalizer DistributedLockKeyNormalizer { get; } public MedallionAbpDistributedLock( IDistributedLockProvider distributedLockProvider, - ICancellationTokenProvider cancellationTokenProvider) + ICancellationTokenProvider cancellationTokenProvider, + IDistributedLockKeyNormalizer distributedLockKeyNormalizer) { DistributedLockProvider = distributedLockProvider; CancellationTokenProvider = cancellationTokenProvider; + DistributedLockKeyNormalizer = distributedLockKeyNormalizer; } public async Task TryAcquireAsync( @@ -27,11 +31,12 @@ public class MedallionAbpDistributedLock : IAbpDistributedLock, ITransientDepend CancellationToken cancellationToken = default) { Check.NotNullOrWhiteSpace(name, nameof(name)); - + var key = DistributedLockKeyNormalizer.NormalizeKey(name); + CancellationTokenProvider.FallbackToProvider(cancellationToken); var handle = await DistributedLockProvider.TryAcquireLockAsync( - name, + key, timeout, CancellationTokenProvider.FallbackToProvider(cancellationToken) ); diff --git a/framework/src/Volo.Abp.Validation/Volo/Abp/Validation/Localization/zh-Hans.json b/framework/src/Volo.Abp.Validation/Volo/Abp/Validation/Localization/zh-Hans.json index 0a41ce1ed5..3c1a566112 100644 --- a/framework/src/Volo.Abp.Validation/Volo/Abp/Validation/Localization/zh-Hans.json +++ b/framework/src/Volo.Abp.Validation/Volo/Abp/Validation/Localization/zh-Hans.json @@ -24,6 +24,8 @@ "ThisFieldMustBeAStringOrArrayTypeWithAMinimumLengthOf{0}": "字段必须是最小长度为'{0}'的字符串或数组.", "ThisFieldIsNotAValidPhoneNumber.": "字段不是有效的手机号码.", "ThisFieldMustBeBetween{0}And{1}": "字段值必须在{0}和{1}范围内.", + "ThisFieldMustBeGreaterThanOrEqual{0}": "该字段必须大于或等于 {0}。", + "ThisFieldMustBeLessOrEqual{0}": "该字段必须小于或等于 {0}。", "ThisFieldMustMatchTheRegularExpression{0}": "字段必须匹配正则表达式'{0}'.", "ThisFieldIsRequired.": "字段不可为空.", "ThisFieldMustBeAStringWithAMaximumLengthOf{0}": "字段必须是长度为{0}的字符串.", @@ -31,4 +33,4 @@ "ThisFieldIsNotAValidFullyQualifiedHttpHttpsOrFtpUrl": "字段{0}不是有效的完全限定的http,https或ftp URL.", "ThisFieldIsInvalid.": "该字段无效." } -} +} \ No newline at end of file diff --git a/modules/account/src/Volo.Abp.Account.Installer/Volo.Abp.Account.Installer.csproj b/modules/account/src/Volo.Abp.Account.Installer/Volo.Abp.Account.Installer.csproj index 7e53ddc078..8ad72ac461 100644 --- a/modules/account/src/Volo.Abp.Account.Installer/Volo.Abp.Account.Installer.csproj +++ b/modules/account/src/Volo.Abp.Account.Installer/Volo.Abp.Account.Installer.csproj @@ -10,7 +10,7 @@ - + diff --git a/modules/account/src/Volo.Abp.Account.Installer/Volo/Abp/Account/AbpAccountInstallerModule.cs b/modules/account/src/Volo.Abp.Account.Installer/Volo/Abp/Account/AbpAccountInstallerModule.cs index 060b47ef68..01d2fa0e3f 100644 --- a/modules/account/src/Volo.Abp.Account.Installer/Volo/Abp/Account/AbpAccountInstallerModule.cs +++ b/modules/account/src/Volo.Abp.Account.Installer/Volo/Abp/Account/AbpAccountInstallerModule.cs @@ -1,11 +1,9 @@ using Volo.Abp.Modularity; -using Volo.Abp.Studio; using Volo.Abp.VirtualFileSystem; namespace Volo.Abp.Account; [DependsOn( - typeof(AbpStudioModuleInstallerModule), typeof(AbpVirtualFileSystemModule) )] public class AbpAccountInstallerModule : AbpModule diff --git a/modules/account/src/Volo.Abp.Account.Installer/Volo/Abp/Account/AccountInstallerPipelineBuilder.cs b/modules/account/src/Volo.Abp.Account.Installer/Volo/Abp/Account/AccountInstallerPipelineBuilder.cs deleted file mode 100644 index 9fb955c9a8..0000000000 --- a/modules/account/src/Volo.Abp.Account.Installer/Volo/Abp/Account/AccountInstallerPipelineBuilder.cs +++ /dev/null @@ -1,16 +0,0 @@ -using System.Threading.Tasks; -using Microsoft.Extensions.DependencyInjection; -using Volo.Abp.DependencyInjection; -using Volo.Abp.Studio.ModuleInstalling; - -namespace Volo.Abp.Account; - -[Dependency(ServiceLifetime.Transient, ReplaceServices = true)] -[ExposeServices(typeof(IModuleInstallingPipelineBuilder))] -public class AccountInstallerPipelineBuilder : ModuleInstallingPipelineBuilderBase, IModuleInstallingPipelineBuilder, ITransientDependency -{ - public async Task BuildAsync(ModuleInstallingContext context) - { - return GetBasePipeline(context); - } -} diff --git a/modules/audit-logging/src/Volo.Abp.AuditLogging.Installer/Volo.Abp.AuditLogging.Installer.csproj b/modules/audit-logging/src/Volo.Abp.AuditLogging.Installer/Volo.Abp.AuditLogging.Installer.csproj index b76f01e430..5a04e797a5 100644 --- a/modules/audit-logging/src/Volo.Abp.AuditLogging.Installer/Volo.Abp.AuditLogging.Installer.csproj +++ b/modules/audit-logging/src/Volo.Abp.AuditLogging.Installer/Volo.Abp.AuditLogging.Installer.csproj @@ -10,7 +10,7 @@ - + diff --git a/modules/audit-logging/src/Volo.Abp.AuditLogging.Installer/Volo/Abp/AuditLogging/AbpAuditLoggingInstallerModule.cs b/modules/audit-logging/src/Volo.Abp.AuditLogging.Installer/Volo/Abp/AuditLogging/AbpAuditLoggingInstallerModule.cs index 52ed214a90..33601e6c40 100644 --- a/modules/audit-logging/src/Volo.Abp.AuditLogging.Installer/Volo/Abp/AuditLogging/AbpAuditLoggingInstallerModule.cs +++ b/modules/audit-logging/src/Volo.Abp.AuditLogging.Installer/Volo/Abp/AuditLogging/AbpAuditLoggingInstallerModule.cs @@ -1,11 +1,9 @@ using Volo.Abp.Modularity; -using Volo.Abp.Studio; using Volo.Abp.VirtualFileSystem; namespace Volo.Abp.AuditLogging; [DependsOn( - typeof(AbpStudioModuleInstallerModule), typeof(AbpVirtualFileSystemModule) )] public class AbpAuditLoggingInstallerModule : AbpModule diff --git a/modules/audit-logging/src/Volo.Abp.AuditLogging.Installer/Volo/Abp/AuditLogging/AuditLoggingInstallerPipelineBuilder.cs b/modules/audit-logging/src/Volo.Abp.AuditLogging.Installer/Volo/Abp/AuditLogging/AuditLoggingInstallerPipelineBuilder.cs deleted file mode 100644 index 94ae5d81fc..0000000000 --- a/modules/audit-logging/src/Volo.Abp.AuditLogging.Installer/Volo/Abp/AuditLogging/AuditLoggingInstallerPipelineBuilder.cs +++ /dev/null @@ -1,23 +0,0 @@ -using System.Threading.Tasks; -using Microsoft.Extensions.DependencyInjection; -using Volo.Abp.DependencyInjection; -using Volo.Abp.Studio.ModuleInstalling; - -namespace Volo.Abp.AuditLogging; - -[Dependency(ServiceLifetime.Transient, ReplaceServices = true)] -[ExposeServices(typeof(IModuleInstallingPipelineBuilder))] -public class AuditLoggingInstallerPipelineBuilder : ModuleInstallingPipelineBuilderBase, IModuleInstallingPipelineBuilder, ITransientDependency -{ - public async Task BuildAsync(ModuleInstallingContext context) - { - context.AddEfCoreConfigurationMethodDeclaration( - new EfCoreConfigurationMethodDeclaration( - "Volo.Abp.AuditLogging.EntityFrameworkCore", - "ConfigureAuditLogging" - ) - ); - - return GetBasePipeline(context); - } -} diff --git a/modules/background-jobs/src/Volo.Abp.BackgroundJobs.Installer/Volo.Abp.BackgroundJobs.Installer.csproj b/modules/background-jobs/src/Volo.Abp.BackgroundJobs.Installer/Volo.Abp.BackgroundJobs.Installer.csproj index 0aba8c2405..05bd0b8f6b 100644 --- a/modules/background-jobs/src/Volo.Abp.BackgroundJobs.Installer/Volo.Abp.BackgroundJobs.Installer.csproj +++ b/modules/background-jobs/src/Volo.Abp.BackgroundJobs.Installer/Volo.Abp.BackgroundJobs.Installer.csproj @@ -10,7 +10,7 @@ - + diff --git a/modules/background-jobs/src/Volo.Abp.BackgroundJobs.Installer/Volo/Abp/BackgroundJobs/AbpBackgroundJobsInstallerModule.cs b/modules/background-jobs/src/Volo.Abp.BackgroundJobs.Installer/Volo/Abp/BackgroundJobs/AbpBackgroundJobsInstallerModule.cs index 1e17c8cfd9..299565ea62 100644 --- a/modules/background-jobs/src/Volo.Abp.BackgroundJobs.Installer/Volo/Abp/BackgroundJobs/AbpBackgroundJobsInstallerModule.cs +++ b/modules/background-jobs/src/Volo.Abp.BackgroundJobs.Installer/Volo/Abp/BackgroundJobs/AbpBackgroundJobsInstallerModule.cs @@ -1,11 +1,9 @@ using Volo.Abp.Modularity; -using Volo.Abp.Studio; using Volo.Abp.VirtualFileSystem; namespace Volo.Abp.BackgroundJobs; [DependsOn( - typeof(AbpStudioModuleInstallerModule), typeof(AbpVirtualFileSystemModule) )] public class AbpBackgroundJobsInstallerModule : AbpModule diff --git a/modules/background-jobs/src/Volo.Abp.BackgroundJobs.Installer/Volo/Abp/BackgroundJobs/BackgroundJobsInstallerPipelineBuilder.cs b/modules/background-jobs/src/Volo.Abp.BackgroundJobs.Installer/Volo/Abp/BackgroundJobs/BackgroundJobsInstallerPipelineBuilder.cs deleted file mode 100644 index ebe2feac61..0000000000 --- a/modules/background-jobs/src/Volo.Abp.BackgroundJobs.Installer/Volo/Abp/BackgroundJobs/BackgroundJobsInstallerPipelineBuilder.cs +++ /dev/null @@ -1,23 +0,0 @@ -using System.Threading.Tasks; -using Microsoft.Extensions.DependencyInjection; -using Volo.Abp.DependencyInjection; -using Volo.Abp.Studio.ModuleInstalling; - -namespace Volo.Abp.BackgroundJobs; - -[Dependency(ServiceLifetime.Transient, ReplaceServices = true)] -[ExposeServices(typeof(IModuleInstallingPipelineBuilder))] -public class BackgroundJobsInstallerPipelineBuilder : ModuleInstallingPipelineBuilderBase, IModuleInstallingPipelineBuilder, ITransientDependency -{ - public async Task BuildAsync(ModuleInstallingContext context) - { - context.AddEfCoreConfigurationMethodDeclaration( - new EfCoreConfigurationMethodDeclaration( - "Volo.Abp.BackgroundJobs.EntityFrameworkCore", - "ConfigureBackgroundJobs" - ) - ); - - return GetBasePipeline(context); - } -} diff --git a/modules/basic-theme/src/Volo.Abp.AspNetCore.Components.Web.BasicTheme/Themes/Basic/MainLayout.razor b/modules/basic-theme/src/Volo.Abp.AspNetCore.Components.Web.BasicTheme/Themes/Basic/MainLayout.razor index 3565d6add5..4d79218662 100644 --- a/modules/basic-theme/src/Volo.Abp.AspNetCore.Components.Web.BasicTheme/Themes/Basic/MainLayout.razor +++ b/modules/basic-theme/src/Volo.Abp.AspNetCore.Components.Web.BasicTheme/Themes/Basic/MainLayout.razor @@ -1,4 +1,6 @@ @using Volo.Abp.Ui.LayoutHooks +@using Volo.Abp.AspNetCore.Components.Web.Theming.Components.LayoutHooks +@using Volo.Abp.AspNetCore.Components.Web.Theming.Components @using Volo.Abp.AspNetCore.Components.Web.Theming.Layout @inherits LayoutComponentBase