diff --git a/docs/en/UI/Angular/Theme-Configurations.md b/docs/en/UI/Angular/Theme-Configurations.md index 85d22040df..1ec4f56c5e 100644 --- a/docs/en/UI/Angular/Theme-Configurations.md +++ b/docs/en/UI/Angular/Theme-Configurations.md @@ -1,3 +1,220 @@ # Angular UI: Theme Configurations -> This document is in draft version. \ No newline at end of file +Theme packages no longer import styles as CSS modules as of ABP version 6.0. The following style settings need to be included to the angular.json file in order for theme packages to load styles. +## Lepton X Lite +```json +{ + "input": "node_modules/@volo/ngx-lepton-x.lite/assets/css/bootstrap-dim.css", + "inject": false, + "bundleName": "bootstrap-dim" +}, +{ + "input": "node_modules/@volo/ngx-lepton-x.lite/assets/css/ng-bundle.css", + "inject": false, + "bundleName": "ng-bundle" +}, +{ + "input": "node_modules/@volo/ngx-lepton-x.lite/assets/css/side-menu/layout-bundle.css", + "inject": false, + "bundleName": "layout-bundle" +}, +{ + "input": "node_modules/@abp/ng.theme.lepton-x/assets/css/abp-bundle.css", + "inject": false, + "bundleName": "abp-bundle" +}, +{ + "input": "node_modules/@volo/ngx-lepton-x.lite/assets/css/bootstrap-dim.rtl.css", + "inject": false, + "bundleName": "bootstrap-dim.rtl" +}, +{ + "input": "node_modules/@volo/ngx-lepton-x.lite/assets/css/ng-bundle.rtl.css", + "inject": false, + "bundleName": "ng-bundle.rtl" +}, +{ + "input": "node_modules/@volo/ngx-lepton-x.lite/assets/css/side-menu/layout-bundle.rtl.css", + "inject": false, + "bundleName": "layout-bundle.rtl" +}, +{ + "input": "node_modules/@abp/ng.theme.lepton-x/assets/css/abp-bundle.rtl.css", + "inject": false, + "bundleName": "abp-bundle.rtl" +}, +``` + +## Theme Basic +```json +{ + "input": "node_modules/bootstrap/dist/css/bootstrap.rtl.min.css", + "inject": false, + "bundleName": "bootstrap-rtl.min" +}, +{ + "input": "node_modules/bootstrap/dist/css/bootstrap.min.css", + "inject": true, + "bundleName": "bootstrap-ltr.min" +}, +``` + +## Lepton X +```json +{ + "input": "node_modules/@volosoft/ngx-lepton-x/assets/css/dark.css", + "inject": false, + "bundleName": "dark" +}, +{ + "input": "node_modules/@volosoft/ngx-lepton-x/assets/css/light.css", + "inject": false, + "bundleName": "light" +}, +{ + "input": "node_modules/@volosoft/ngx-lepton-x/assets/css/dim.css", + "inject": false, + "bundleName": "dim" +}, +{ + "input": "node_modules/@volosoft/ngx-lepton-x/assets/css/bootstrap-dim.css", + "inject": false, + "bundleName": "bootstrap-dim" +}, +{ + "input": "node_modules/@volosoft/ngx-lepton-x/assets/css/bootstrap-dark.css", + "inject": false, + "bundleName": "bootstrap-dark" +}, +{ + "input": "node_modules/@volosoft/ngx-lepton-x/assets/css/bootstrap-light.css", + "inject": false, + "bundleName": "bootstrap-light" +}, +{ + "input": "node_modules/@volosoft/ngx-lepton-x/assets/css/ng-bundle.css", + "inject": false, + "bundleName": "ng-bundle" +}, +{ + "input": "node_modules/@volosoft/ngx-lepton-x/assets/css/side-menu/layout-bundle.css", + "inject": false, + "bundleName": "layout-bundle" +}, +{ + "input": "node_modules/@volosoft/abp.ng.theme.lepton-x/assets/css/abp-bundle.css", + "inject": false, + "bundleName": "abp-bundle" +}, +{ + "input": "node_modules/@volosoft/ngx-lepton-x/assets/css/dark.rtl.css", + "inject": false, + "bundleName": "dark.rtl" +}, +{ + "input": "node_modules/@volosoft/ngx-lepton-x/assets/css/light.rtl.css", + "inject": false, + "bundleName": "light.rtl" +}, +{ + "input": "node_modules/@volosoft/ngx-lepton-x/assets/css/dim.rtl.css", + "inject": false, + "bundleName": "dim.rtl" +}, +{ + "input": "node_modules/@volosoft/ngx-lepton-x/assets/css/bootstrap-dim.rtl.css", + "inject": false, + "bundleName": "bootstrap-dim.rtl" +}, +{ + "input": "node_modules/@volosoft/ngx-lepton-x/assets/css/bootstrap-dark.rtl.css", + "inject": false, + "bundleName": "bootstrap-dark.rtl" +}, +{ + "input": "node_modules/@volosoft/ngx-lepton-x/assets/css/bootstrap-light.rtl.css", + "inject": false, + "bundleName": "bootstrap-light.rtl" +}, +{ + "input": "node_modules/@volosoft/ngx-lepton-x/assets/css/ng-bundle.rtl.css", + "inject": false, + "bundleName": "ng-bundle.rtl" +}, +{ + "input": "node_modules/@volosoft/ngx-lepton-x/assets/css/side-menu/layout-bundle.rtl.css", + "inject": false, + "bundleName": "layout-bundle.rtl" +}, +{ + "input": "node_modules/@volosoft/abp.ng.theme.lepton-x/assets/css/abp-bundle.rtl.css", + "inject": false, + "bundleName": "abp-bundle.rtl" +} +``` + +## Theme Lepton +```json +{ + "input": "node_modules/@volo/abp.ng.theme.lepton/dist/global/styles/lepton1.min.css", + "inject": false, + "bundleName": "lepton1" +}, +{ + "input": "node_modules/@volo/abp.ng.theme.lepton/dist/global/styles/lepton2.min.css", + "inject": false, + "bundleName": "lepton2" +}, +{ + "input": "node_modules/@volo/abp.ng.theme.lepton/dist/global/styles/lepton3.min.css", + "inject": false, + "bundleName": "lepton3" +}, +{ + "input": "node_modules/@volo/abp.ng.theme.lepton/dist/global/styles/lepton4.min.css", + "inject": false, + "bundleName": "lepton4" +}, +{ + "input": "node_modules/@volo/abp.ng.theme.lepton/dist/global/styles/lepton5.min.css", + "inject": false, + "bundleName": "lepton5" +}, +{ + "input": "node_modules/@volo/abp.ng.theme.lepton/dist/global/styles/lepton6.min.css", + "inject": false, + "bundleName": "lepton6" +}, +{ + "input": "node_modules/@volo/abp.ng.theme.lepton/dist/global/styles/lepton1.rtl.min.css", + "inject": false, + "bundleName": "lepton1.rtl" +}, +{ + "input": "node_modules/@volo/abp.ng.theme.lepton/dist/global/styles/lepton2.rtl.min.css", + "inject": false, + "bundleName": "lepton2.rtl" +}, +{ + "input": "node_modules/@volo/abp.ng.theme.lepton/dist/global/styles/lepton3.rtl.min.css", + "inject": false, + "bundleName": "lepton3.rtl" +}, +{ + "input": "node_modules/@volo/abp.ng.theme.lepton/dist/global/styles/lepton4.rtl.min.css", + "inject": false, + "bundleName": "lepton4.rtl" +}, +{ + "input": "node_modules/@volo/abp.ng.theme.lepton/dist/global/styles/lepton5.rtl.min.css", + "inject": false, + "bundleName": "lepton5.rtl" +}, +{ + "input": "node_modules/@volo/abp.ng.theme.lepton/dist/global/styles/lepton6.rtl.min.css", + "inject": false, + "bundleName": "lepton6.rtl" +}, +``` + + diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ContentFormatters/RemoteStreamContentOutputFormatter.cs b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ContentFormatters/RemoteStreamContentOutputFormatter.cs index 5c5e7ed6c0..e41616617d 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ContentFormatters/RemoteStreamContentOutputFormatter.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ContentFormatters/RemoteStreamContentOutputFormatter.cs @@ -27,7 +27,7 @@ public class RemoteStreamContentOutputFormatter : OutputFormatter context.HttpContext.Response.ContentType = remoteStream.ContentType; context.HttpContext.Response.ContentLength = remoteStream.ContentLength; - if (!remoteStream.FileName.IsNullOrWhiteSpace()) + if (!remoteStream.FileName.IsNullOrWhiteSpace() && !context.HttpContext.Response.Headers.ContainsKey(HeaderNames.ContentDisposition)) { var contentDisposition = new ContentDispositionHeaderValue("attachment"); contentDisposition.SetHttpFileName(remoteStream.FileName); diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/ContentFormatters/RemoteStreamContentTestController.cs b/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/ContentFormatters/RemoteStreamContentTestController.cs index 42c84a8037..5efebb4603 100644 --- a/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/ContentFormatters/RemoteStreamContentTestController.cs +++ b/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/ContentFormatters/RemoteStreamContentTestController.cs @@ -19,6 +19,27 @@ public class RemoteStreamContentTestController : AbpController memoryStream.Position = 0; return new RemoteStreamContent(memoryStream, "download.rtf", "application/rtf"); } + + [HttpGet] + [Route("Download-With-Custom-Content-Disposition")] + public async Task Download_With_Custom_Content_Disposition_Async() + { + var memoryStream = new MemoryStream(); + await memoryStream.WriteAsync(Encoding.UTF8.GetBytes("DownloadAsync")); + memoryStream.Position = 0; + Response.Headers.Add("Content-Disposition", "attachment; filename=myDownload.rtf"); + return new RemoteStreamContent(memoryStream, "download.rtf", "application/rtf"); + } + + [HttpGet] + [Route("Download_With_Chinese_File_Name")] + public async Task Download_With_Chinese_File_Name_Async() + { + var memoryStream = new MemoryStream(); + await memoryStream.WriteAsync(Encoding.UTF8.GetBytes("DownloadAsync")); + memoryStream.Position = 0; + return new RemoteStreamContent(memoryStream, "下载文件.rtf", "application/rtf"); + } [HttpPost] [Route("Upload")] diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/ContentFormatters/RemoteStreamContentTestController_Tests.cs b/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/ContentFormatters/RemoteStreamContentTestController_Tests.cs index 1a60ab9d6b..321c0099f1 100644 --- a/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/ContentFormatters/RemoteStreamContentTestController_Tests.cs +++ b/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/ContentFormatters/RemoteStreamContentTestController_Tests.cs @@ -3,6 +3,7 @@ using System.Net.Http; using System.Net.Http.Headers; using System.Text; using System.Threading.Tasks; +using System.Web; using Shouldly; using Xunit; @@ -19,6 +20,26 @@ public class RemoteStreamContentTestController_Tests : AspNetCoreMvcTestBase result.Content.Headers.ContentLength.ShouldBe("DownloadAsync".Length); (await result.Content.ReadAsStringAsync()).ShouldBe("DownloadAsync"); } + + [Fact] + public async Task Download_With_Custom_Content_Disposition_Async() + { + var result = await GetResponseAsync("/api/remote-stream-content-test/download-with-custom-content-disposition"); + result.Content.Headers.ContentType?.ToString().ShouldBe("application/rtf"); + result.Content.Headers.ContentDisposition?.FileName.ShouldBe("myDownload.rtf"); + result.Content.Headers.ContentLength.ShouldBe("DownloadAsync".Length); + (await result.Content.ReadAsStringAsync()).ShouldBe("DownloadAsync"); + } + + [Fact] + public async Task Download_With_Chinese_File_Name_Async() + { + var result = await GetResponseAsync("/api/remote-stream-content-test/download_with_chinese_file_name"); + result.Content.Headers.ContentType?.ToString().ShouldBe("application/rtf"); + result.Content.Headers.ContentDisposition?.FileNameStar.ShouldBe("下载文件.rtf"); + result.Content.Headers.ContentLength.ShouldBe("DownloadAsync".Length); + (await result.Content.ReadAsStringAsync()).ShouldBe("DownloadAsync"); + } [Fact] public async Task UploadAsync()