diff --git a/Directory.Packages.props b/Directory.Packages.props index 01d1a458ca..9b3c349f59 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -114,7 +114,7 @@ - + @@ -125,7 +125,7 @@ - + diff --git a/docs/en/cli/index.md b/docs/en/cli/index.md index 75e6a17bb9..61d5986588 100644 --- a/docs/en/cli/index.md +++ b/docs/en/cli/index.md @@ -227,15 +227,15 @@ For more samples, go to [ABP CLI Create Solution Samples](new-command-samples.md * `--no-kubernetes-configuration` or `-nkc`: Skips the Kubernetes configuration files. * `--no-social-logins` or `-nsl`: Skipts the social login configuration. * `--no-tests` or `-ntp`: Does not add test projects. -* *Module Options*: You can skip some modules if you don't want to add them to your solution (*Available for* ***Team*** *or higher licenses*). Available commands: +* *Module Options*: You can skip some modules if you don't want to add them to your solution, or include if you want them (*Available for* ***Team*** *or higher licenses*). Available commands: * `-no-saas`: Skips the Saas module. * `-no-gdpr`: Skips the GDPR module. * `-no-openiddict-admin-ui`: Skips the OpenIddict Admin UI module. * `-no-audit-logging`: Skips the Audit Logging module. - * `-no-file-management`: Skips the File Management module. * `-no-language-management`: Skips the Language Management module. * `-no-text-template-management`: Skips the Text Template Management module. - * `-no-chat`: Skips the Chat module. + * `-file-management`: Includes the File Management module. + * `-chat`: Includes the Chat module. * `--legacy`: Generates a legacy solution. * `trust-version`: Trusts the user's version and does not check if the version exists or not. If the template with the given version is found in the cache, it will be used, otherwise throws an exception. diff --git a/docs/en/framework/ui/maui/index.md b/docs/en/framework/ui/maui/index.md index 69f9518e92..573278a060 100644 --- a/docs/en/framework/ui/maui/index.md +++ b/docs/en/framework/ui/maui/index.md @@ -40,6 +40,9 @@ Open a command line terminal and run the `adb reverse` command to expose a port > You should replace "44305" with the real port. > You should run the command after starting the emulator. +> If you don't have a separate installation of Android Debug Bridge, you can open it from **Visual Studio** by following toolbar menu `Tools` > `Android` > `Android Adb Command Prompt`. Android emulator has to be running for this operation. + + ### iOS The iOS simulator uses the host machine network. Therefore, applications running in the simulator can connect to web services running on your local machine via the machines IP address or via the localhost hostname. For example, given a local secure web service that exposes a GET operation via the /api/todoitems/ relative URI, an application running on the iOS simulator can consume the operation by sending a GET request to https://localhost:/api/todoitems/. diff --git a/docs/en/solution-templates/microservice/guides/add-new-microservice.md b/docs/en/solution-templates/microservice/guides/add-new-microservice.md index 12c8b527e8..f68f315dd7 100644 --- a/docs/en/solution-templates/microservice/guides/add-new-microservice.md +++ b/docs/en/solution-templates/microservice/guides/add-new-microservice.md @@ -1,3 +1 @@ -# ABP Studio Microservice Solution: Adding New Microservices - -This document is planned to be written later. \ No newline at end of file +> This document is [moved to here](../adding-new-microservices.md). \ No newline at end of file diff --git a/docs/en/studio/release-notes.md b/docs/en/studio/release-notes.md index 6d5016d111..282d038c5e 100644 --- a/docs/en/studio/release-notes.md +++ b/docs/en/studio/release-notes.md @@ -2,6 +2,13 @@ This document contains **brief release notes** for each ABP Studio release. Release notes only include **major features** and **visible enhancements**. Therefore, they don't include all the development done in the related version. +## 0.9.15 (2024-12-05) + +* Upgraded templates to version `9.0.1`. +* Fixed problems in the microservice service_nolayers template. +* Fixed microservice angular template for wrong file-management module reference. +* Fixed added extra lines in the hosts.txt file. + ## 0.9.14 (2024-12-03) * Refactored `dotnet watch` command in solution runner. diff --git a/docs/en/studio/version-mapping.md b/docs/en/studio/version-mapping.md index 428282ea48..fe91ffe89a 100644 --- a/docs/en/studio/version-mapping.md +++ b/docs/en/studio/version-mapping.md @@ -4,6 +4,7 @@ This document provides a general overview of the relationship between various ve | **ABP Studio Version** | **ABP Version of Startup Template** | |------------------------|---------------------------| +| 0.9.15 | 9.0.1 | | 0.9.9 to 0.9.14 | 9.0.0 | | 0.9.8 | 8.3.4 | | 0.9.5 to 0.9.7 | 8.3.3 | diff --git a/framework/src/Volo.Abp.AspNetCore/Microsoft/AspNetCore/Builder/AbpApplicationBuilderExtensions.cs b/framework/src/Volo.Abp.AspNetCore/Microsoft/AspNetCore/Builder/AbpApplicationBuilderExtensions.cs index bd653faf55..3cada3bf46 100644 --- a/framework/src/Volo.Abp.AspNetCore/Microsoft/AspNetCore/Builder/AbpApplicationBuilderExtensions.cs +++ b/framework/src/Volo.Abp.AspNetCore/Microsoft/AspNetCore/Builder/AbpApplicationBuilderExtensions.cs @@ -15,6 +15,7 @@ using Volo.Abp.AspNetCore.Auditing; using Volo.Abp.AspNetCore.ExceptionHandling; using Volo.Abp.AspNetCore.Security; using Volo.Abp.AspNetCore.Security.Claims; +using Volo.Abp.AspNetCore.StaticFiles; using Volo.Abp.AspNetCore.Tracing; using Volo.Abp.AspNetCore.Uow; using Volo.Abp.AspNetCore.VirtualFileSystem; @@ -126,6 +127,38 @@ public static class AbpApplicationBuilderExtensions return app.UseMiddleware(); } + /// + /// Configures the application to serve static files that match the specified filename patterns with the WebRootFileProvider of the application. + /// + /// The used to configure the application pipeline. + /// The file name patterns to include when serving static files (e.g., "appsettings*.json"). + /// Supports glob patterns. See Glob patterns documentation. + /// + /// The instance. + public static IApplicationBuilder UseStaticFilesForPatterns(this IApplicationBuilder app, params string[] includeFileNamePatterns) + { + return UseStaticFilesForPatterns(app, includeFileNamePatterns, app.ApplicationServices.GetRequiredService().WebRootFileProvider); + } + + /// + /// Configures the application to serve static files that match the specified filename patterns with the specified file provider. + /// + /// The used to configure the application pipeline. + /// The file name patterns to include when serving static files (e.g., "appsettings*.json"). + /// Supports glob patterns. See Glob patterns documentation. + /// + /// The + /// The instance. + public static IApplicationBuilder UseStaticFilesForPatterns(this IApplicationBuilder app, string[] includeFileNamePatterns, IFileProvider fileProvider) + { + app.UseStaticFiles(new StaticFileOptions + { + FileProvider = new AbpStaticFileProvider(includeFileNamePatterns, fileProvider) + }); + + return app; + } + /// /// MapAbpStaticAssets is used to serve the files from the abp virtual file system embedded resources(js/css) and call the MapStaticAssets. /// diff --git a/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/StaticFiles/AbpStaticFileProvider.cs b/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/StaticFiles/AbpStaticFileProvider.cs new file mode 100644 index 0000000000..f7893932f2 --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/StaticFiles/AbpStaticFileProvider.cs @@ -0,0 +1,42 @@ +using System; +using System.Collections.Generic; +using System.IO; +using Microsoft.Extensions.FileProviders; +using Microsoft.Extensions.FileSystemGlobbing; +using Microsoft.Extensions.Primitives; + +namespace Volo.Abp.AspNetCore.StaticFiles; + +public class AbpStaticFileProvider : IFileProvider +{ + private readonly Matcher _matcher; + private readonly IFileProvider _fileProvider; + + /// The file provider to be used to get the files. + /// The file name patterns to include when serving static files (e.g., "appsettings*.json"). + /// Supports glob patterns. See Glob patterns documentation. + /// + public AbpStaticFileProvider(IReadOnlyList fileNamePatterns, IFileProvider fileProvider) + { + _fileProvider = fileProvider; + _matcher = new Matcher(StringComparison.OrdinalIgnoreCase); + _matcher.AddIncludePatterns(fileNamePatterns); + } + + public IDirectoryContents GetDirectoryContents(string subpath) + { + return new NotFoundDirectoryContents(); + } + + public IFileInfo GetFileInfo(string subpath) + { + return _matcher.Match(Path.GetFileName(subpath)).HasMatches ? + _fileProvider.GetFileInfo(subpath) : + new NotFoundFileInfo(subpath); + } + + public IChangeToken Watch(string filter) + { + return NullChangeToken.Singleton; + } +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Auth/AuthService.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Auth/AuthService.cs index 8695c0c418..333ae59e3f 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Auth/AuthService.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Auth/AuthService.cs @@ -85,7 +85,11 @@ public class AuthService : IAuthService, ITransientDependency } var accessToken = await AuthenticationService.GetAccessTokenAsync(configuration); - + + if (!Directory.Exists(CliPaths.Root)) + { + Directory.CreateDirectory(CliPaths.Root); + } File.WriteAllText(CliPaths.AccessToken, accessToken, Encoding.UTF8); } diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/VoloNugetPackagesVersionUpdater.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/VoloNugetPackagesVersionUpdater.cs index 9f23645fb9..4ece393913 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/VoloNugetPackagesVersionUpdater.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/VoloNugetPackagesVersionUpdater.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; using NuGet.Versioning; using System.IO; using System.Linq; @@ -39,6 +40,7 @@ public class VoloNugetPackagesVersionUpdater : ITransientDependency var latestVersionInfo = await _packageVersionCheckerService.GetLatestVersionOrNullAsync("Volo.Abp.Core", includeReleaseCandidates: includeReleaseCandidates); var latestReleaseCandidateVersionInfo = await _packageVersionCheckerService.GetLatestVersionOrNullAsync("Volo.Abp.Core", includeReleaseCandidates: true); var latestVersionFromMyGet = await GetLatestVersionFromMyGet("Volo.Abp.Core"); + var latestStableVersions = await _packageVersionCheckerService.GetLatestStableVersionsAsync(); async Task UpdateAsync(string filePath) { @@ -55,7 +57,8 @@ public class VoloNugetPackagesVersionUpdater : ITransientDependency latestVersionInfo.Version, latestReleaseCandidateVersionInfo.Version, latestVersionFromMyGet, - version); + version, + latestStableVersions: latestStableVersions); fs.Seek(0, SeekOrigin.Begin); fs.SetLength(0); @@ -83,6 +86,7 @@ public class VoloNugetPackagesVersionUpdater : ITransientDependency var latestVersionInfo = await _packageVersionCheckerService.GetLatestVersionOrNullAsync("Volo.Abp.Core"); var latestReleaseCandidateVersionInfo = await _packageVersionCheckerService.GetLatestVersionOrNullAsync("Volo.Abp.Core", includeReleaseCandidates: true); var latestVersionFromMyGet = await GetLatestVersionFromMyGet("Volo.Abp.Core"); + var latestStableVersions = await _packageVersionCheckerService.GetLatestStableVersionsAsync(); using (var fs = File.Open(projectPath, FileMode.Open, FileAccess.ReadWrite, FileShare.None)) { @@ -97,7 +101,8 @@ public class VoloNugetPackagesVersionUpdater : ITransientDependency latestVersionInfo.Version, latestReleaseCandidateVersionInfo.Version, latestVersionFromMyGet, - version); + version, + latestStableVersions: latestStableVersions); fs.Seek(0, SeekOrigin.Begin); fs.SetLength(0); @@ -114,13 +119,20 @@ public class VoloNugetPackagesVersionUpdater : ITransientDependency protected virtual async Task UpdateInternalAsync(string projectPath, bool includeNightlyPreviews = false, bool includeReleaseCandidates = false, bool switchToStable = false) { + var latestStableVersions = await _packageVersionCheckerService.GetLatestStableVersionsAsync(); + using (var fs = File.Open(projectPath, FileMode.Open, FileAccess.ReadWrite, FileShare.None)) { using (var sr = new StreamReader(fs, Encoding.Default, true)) { var fileContent = await sr.ReadToEndAsync(); - var updatedContent = await UpdateVoloPackagesAsync(fileContent, includeNightlyPreviews, includeReleaseCandidates, switchToStable); + var updatedContent = await UpdateVoloPackagesAsync( + fileContent, + includeNightlyPreviews, + includeReleaseCandidates, + switchToStable, + latestStableVersions: latestStableVersions); fs.Seek(0, SeekOrigin.Begin); fs.SetLength(0); @@ -153,7 +165,8 @@ public class VoloNugetPackagesVersionUpdater : ITransientDependency SemanticVersion latestNugetVersion = null, SemanticVersion latestNugetReleaseCandidateVersion = null, string latestMyGetVersion = null, - string specifiedVersion = null) + string specifiedVersion = null, + List latestStableVersions = null) { string packageId = null; @@ -206,29 +219,39 @@ public class VoloNugetPackagesVersionUpdater : ITransientDependency if (!specifiedVersion.IsNullOrWhiteSpace()) { - if (isLeptonXPackage || isStudioPackage) + var leptonXPackageVersion = latestStableVersions? + .FirstOrDefault(v => v.Version.Equals(specifiedVersion, StringComparison.InvariantCultureIgnoreCase))?.LeptonX?.Version; + + if ((isLeptonXPackage && string.IsNullOrWhiteSpace(leptonXPackageVersion)) || isStudioPackage) { Logger.LogWarning("Package: {PackageId} could not be updated. Please manually update the package version yourself to prevent version mismatches!", packageId); continue; } - if (await SpecifiedVersionExists(specifiedVersion, packageId)) + var isLeptonXPackageWithVersion = isLeptonXPackage && !string.IsNullOrWhiteSpace(leptonXPackageVersion); + + if (isLeptonXPackageWithVersion || await SpecifiedVersionExists(specifiedVersion, packageId)) + { + TryUpdatingPackage(isLeptonXPackageWithVersion ? leptonXPackageVersion : specifiedVersion); + } + else { - var specifiedSemanticVersion = SemanticVersion.Parse(specifiedVersion); + Logger.LogWarning("Package \"{PackageId}\" specified version v{SpecifiedVersion} does not exist!", packageId, specifiedVersion); + } + + void TryUpdatingPackage(string versionToUpdate) + { + var specifiedSemanticVersion = SemanticVersion.Parse(versionToUpdate); if (specifiedSemanticVersion > currentSemanticVersion) { - Logger.LogInformation("Updating package \"{PackageId}\" from v{CurrentVersion} to v{SpecifiedVersion}", packageId, currentVersion, specifiedVersion); - versionAttribute.Value = specifiedVersion; + Logger.LogInformation("Updating package \"{PackageId}\" from v{CurrentVersion} to v{SpecifiedVersion}", packageId, currentVersion, versionToUpdate); + versionAttribute.Value = versionToUpdate; } else { - Logger.LogWarning("Unable to update package \"{PackageId}\" version v{CurrentVersion} to v{SpecifiedVersion}", packageId, currentVersion, specifiedVersion); + Logger.LogWarning("Unable to update package \"{PackageId}\" version v{CurrentVersion} to v{SpecifiedVersion}", packageId, currentVersion, versionToUpdate); } } - else - { - Logger.LogWarning("Package \"{PackageId}\" specified version v{SpecifiedVersion} does not exist!", packageId, specifiedVersion); - } } else { @@ -252,7 +275,7 @@ public class VoloNugetPackagesVersionUpdater : ITransientDependency } else { - latestVersion = latestMyGetVersion == null ? await GetLatestVersionFromMyGet(packageId) : latestMyGetVersion; + latestVersion = latestMyGetVersion ?? await GetLatestVersionFromMyGet(packageId); } if(latestVersion == null) diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Version/PackageVersionCheckerService.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Version/PackageVersionCheckerService.cs index d5764c1c0e..316c53e01e 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Version/PackageVersionCheckerService.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Version/PackageVersionCheckerService.cs @@ -5,6 +5,7 @@ using System.Collections.Generic; using System.Linq; using System.Net; using System.Threading.Tasks; +using JetBrains.Annotations; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging.Abstractions; using Volo.Abp.Cli.Http; @@ -111,6 +112,11 @@ public class PackageVersionCheckerService : ITransientDependency ? new LatestVersionInfo(semanticVersion, latestStableVersionResult.Message) : null; } + + public async Task> GetLatestStableVersionsAsync() + { + return await GetLatestStableVersionsInternalAsync(); + } private static ConcurrentDictionary CommercialPackagesCache { get; } = new (); @@ -225,7 +231,7 @@ public class PackageVersionCheckerService : ITransientDependency _apiKeyResult ??= await _apiKeyService.GetApiKeyOrNullAsync(); } - private async Task GetLatestStableVersionOrNullAsync() + private async Task> GetLatestStableVersionsInternalAsync() { try { @@ -241,16 +247,24 @@ public class PackageVersionCheckerService : ITransientDependency var content = await responseMessage.Content.ReadAsStringAsync(); var result = JsonSerializer.Deserialize>(content); - - return result.FirstOrDefault(x => x.Type.ToLowerInvariant() == "stable"); + return result.OrderBy(q => q.Type.ToLowerInvariant() == "stable").ThenBy(q => SemanticVersion.Parse(q.Version)).ToList(); } } catch { - return null; + return []; } } + private async Task GetLatestStableVersionOrNullAsync() + { + var latestStableVersionsResult = await GetLatestStableVersionsInternalAsync(); + + return latestStableVersionsResult.Count <= 0 + ? null + : latestStableVersionsResult.FirstOrDefault(); + } + public class NuGetSearchResultDto { public int TotalHits { get; set; } @@ -270,6 +284,11 @@ public class PackageVersionCheckerService : ITransientDependency public List Versions { get; set; } } + public class LeptonXThemeInfo + { + public string Version { get; set; } + } + public class LatestStableVersionResult { public string Version { get; set; } @@ -279,5 +298,8 @@ public class PackageVersionCheckerService : ITransientDependency public string Type { get; set; } public string Message { get; set; } + + [CanBeNull] + public LeptonXThemeInfo LeptonX { get; set; } } } diff --git a/framework/src/Volo.Abp.EntityFrameworkCore.Oracle/Volo.Abp.EntityFrameworkCore.Oracle.csproj b/framework/src/Volo.Abp.EntityFrameworkCore.Oracle/Volo.Abp.EntityFrameworkCore.Oracle.csproj index 2948ef0cfb..8f14308ed6 100644 --- a/framework/src/Volo.Abp.EntityFrameworkCore.Oracle/Volo.Abp.EntityFrameworkCore.Oracle.csproj +++ b/framework/src/Volo.Abp.EntityFrameworkCore.Oracle/Volo.Abp.EntityFrameworkCore.Oracle.csproj @@ -21,7 +21,6 @@ - diff --git a/latest-versions.json b/latest-versions.json index 27908ad9cb..e2c60800a3 100644 --- a/latest-versions.json +++ b/latest-versions.json @@ -3,6 +3,27 @@ "version": "9.0.1", "releaseDate": "", "type": "stable", - "message": "" + "message": "", + "leptonx": { + "version": "4.0.1" + } + }, + { + "version": "9.0.0", + "releaseDate": "", + "type": "stable", + "message": "", + "leptonx": { + "version": "4.0.0" + } + }, + { + "version": "8.3.1", + "releaseDate": "", + "type": "stable", + "message": "", + "leptonx": { + "version": "3.3.1" + } } ] \ No newline at end of file diff --git a/modules/permission-management/src/Volo.Abp.PermissionManagement.Blazor/Components/PermissionManagementModal.razor.cs b/modules/permission-management/src/Volo.Abp.PermissionManagement.Blazor/Components/PermissionManagementModal.razor.cs index 50e6035b9b..a0b7de8c07 100644 --- a/modules/permission-management/src/Volo.Abp.PermissionManagement.Blazor/Components/PermissionManagementModal.razor.cs +++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.Blazor/Components/PermissionManagementModal.razor.cs @@ -154,7 +154,7 @@ public partial class PermissionManagementModal var updateDto = new UpdatePermissionsDto { - Permissions = _groups + Permissions = _allGroups .SelectMany(g => g.Permissions) .Select(p => new UpdatePermissionDto { IsGranted = p.IsGranted, Name = p.Name }) .ToArray()