diff --git a/Oqtane.Server/wwwroot/Modules/Templates/External/Client/Modules/[Owner].Module.[Module]/Index.razor b/Oqtane.Server/wwwroot/Modules/Templates/External/Client/Modules/[Owner].Module.[Module]/Index.razor index 91eef0a1..ac84a97e 100644 --- a/Oqtane.Server/wwwroot/Modules/Templates/External/Client/Modules/[Owner].Module.[Module]/Index.razor +++ b/Oqtane.Server/wwwroot/Modules/Templates/External/Client/Modules/[Owner].Module.[Module]/Index.razor @@ -26,7 +26,7 @@ else - + @context.Name @@ -38,6 +38,9 @@ else } @code { + // uncomment the following line to use Static render mode for this component + // public override string RenderMode => RenderModes.Static; + public override List Resources => new List() { new Resource { ResourceType = ResourceType.Stylesheet, Url = ModulePath() + "Module.css" }, diff --git a/Oqtane.Server/wwwroot/Modules/Templates/External/Client/Services/[Module]Service.cs b/Oqtane.Server/wwwroot/Modules/Templates/External/Client/Services/[Module]Service.cs index fbcd1bef..e91fc97d 100644 --- a/Oqtane.Server/wwwroot/Modules/Templates/External/Client/Services/[Module]Service.cs +++ b/Oqtane.Server/wwwroot/Modules/Templates/External/Client/Services/[Module]Service.cs @@ -5,13 +5,12 @@ using System.Threading.Tasks; using Oqtane.Modules; using Oqtane.Services; using Oqtane.Shared; -using [Owner].Module.[Module].Models; namespace [Owner].Module.[Module].Services { public class [Module]Service : ServiceBase, I[Module]Service, IService { - public [Module]Service(HttpClient http, SiteState siteState) : base(http, siteState) { } + public [Module]Service(IHttpClientFactory http, SiteState siteState) : base(http, siteState) { } private string Apiurl => CreateApiUrl("[Module]"); diff --git a/Oqtane.Server/wwwroot/Modules/Templates/External/Client/[Owner].Module.[Module].Client.csproj b/Oqtane.Server/wwwroot/Modules/Templates/External/Client/[Owner].Module.[Module].Client.csproj index 4185ac8e..6653d33f 100644 --- a/Oqtane.Server/wwwroot/Modules/Templates/External/Client/[Owner].Module.[Module].Client.csproj +++ b/Oqtane.Server/wwwroot/Modules/Templates/External/Client/[Owner].Module.[Module].Client.csproj @@ -17,6 +17,7 @@ + diff --git a/Oqtane.Server/wwwroot/Modules/Templates/External/Server/Manager/[Module]Manager.cs b/Oqtane.Server/wwwroot/Modules/Templates/External/Server/Manager/[Module]Manager.cs index 17553cc8..4be95aa7 100644 --- a/Oqtane.Server/wwwroot/Modules/Templates/External/Server/Manager/[Module]Manager.cs +++ b/Oqtane.Server/wwwroot/Modules/Templates/External/Server/Manager/[Module]Manager.cs @@ -1,7 +1,6 @@ using System.Collections.Generic; using System.Linq; using System.Text.Json; -using Microsoft.AspNetCore.Http; using Oqtane.Modules; using Oqtane.Models; using Oqtane.Infrastructure; diff --git a/Oqtane.Server/wwwroot/Modules/Templates/External/Server/Repository/I[Module]Repository.cs b/Oqtane.Server/wwwroot/Modules/Templates/External/Server/Repository/I[Module]Repository.cs index 959cac4a..ded5d3ed 100644 --- a/Oqtane.Server/wwwroot/Modules/Templates/External/Server/Repository/I[Module]Repository.cs +++ b/Oqtane.Server/wwwroot/Modules/Templates/External/Server/Repository/I[Module]Repository.cs @@ -1,5 +1,5 @@ using System.Collections.Generic; -using [Owner].Module.[Module].Models; +using System.Threading.Tasks; namespace [Owner].Module.[Module].Repository { @@ -11,5 +11,12 @@ namespace [Owner].Module.[Module].Repository Models.[Module] Add[Module](Models.[Module] [Module]); Models.[Module] Update[Module](Models.[Module] [Module]); void Delete[Module](int [Module]Id); + + Task> Get[Module]sAsync(int ModuleId); + Task Get[Module]Async(int [Module]Id); + Task Get[Module]Async(int [Module]Id, bool tracking); + Task Add[Module]Async(Models.[Module] [Module]); + Task Update[Module]Async(Models.[Module] [Module]); + Task Delete[Module]Async(int [Module]Id); } } diff --git a/Oqtane.Server/wwwroot/Modules/Templates/External/Server/Repository/[Module]Repository.cs b/Oqtane.Server/wwwroot/Modules/Templates/External/Server/Repository/[Module]Repository.cs index 2e6229e2..5a8641e9 100644 --- a/Oqtane.Server/wwwroot/Modules/Templates/External/Server/Repository/[Module]Repository.cs +++ b/Oqtane.Server/wwwroot/Modules/Templates/External/Server/Repository/[Module]Repository.cs @@ -2,24 +2,23 @@ using Microsoft.EntityFrameworkCore; using System.Linq; using System.Collections.Generic; using Oqtane.Modules; -using [Owner].Module.[Module].Models; +using System.Threading.Tasks; namespace [Owner].Module.[Module].Repository { public class [Module]Repository : I[Module]Repository, ITransientService { private readonly IDbContextFactory<[Module]Context> _factory; - private readonly [Module]Context _queryContext; public [Module]Repository(IDbContextFactory<[Module]Context> factory) { _factory = factory; - _queryContext = _factory.CreateDbContext(); } public IEnumerable Get[Module]s(int ModuleId) { - return _queryContext.[Module].Where(item => item.ModuleId == ModuleId); + using var db = _factory.CreateDbContext(); + return db.[Module].Where(item => item.ModuleId == ModuleId).ToList(); } public Models.[Module] Get[Module](int [Module]Id) @@ -63,5 +62,54 @@ namespace [Owner].Module.[Module].Repository db.[Module].Remove([Module]); db.SaveChanges(); } + + + public async Task> Get[Module]sAsync(int ModuleId) + { + using var db = _factory.CreateDbContext(); + return await db.[Module].Where(item => item.ModuleId == ModuleId).ToListAsync(); + } + + public async Task Get[Module]Async(int [Module]Id) + { + return await Get[Module]Async([Module]Id, true); + } + + public async Task Get[Module]Async(int [Module]Id, bool tracking) + { + using var db = _factory.CreateDbContext(); + if (tracking) + { + return await db.[Module].FindAsync([Module]Id); + } + else + { + return await db.[Module].AsNoTracking().FirstOrDefaultAsync(item => item.[Module]Id == [Module]Id); + } + } + + public async Task Add[Module]Async(Models.[Module] [Module]) + { + using var db = _factory.CreateDbContext(); + db.[Module].Add([Module]); + await db.SaveChangesAsync(); + return [Module]; + } + + public async Task Update[Module]Async(Models.[Module] [Module]) + { + using var db = _factory.CreateDbContext(); + db.Entry([Module]).State = EntityState.Modified; + await db.SaveChangesAsync(); + return [Module]; + } + + public async Task Delete[Module]Async(int [Module]Id) + { + using var db = _factory.CreateDbContext(); + Models.[Module] [Module] = db.[Module].Find([Module]Id); + db.[Module].Remove([Module]); + await db.SaveChangesAsync(); + } } } diff --git a/Oqtane.Server/wwwroot/Modules/Templates/External/Server/Services/[Module]Service.cs b/Oqtane.Server/wwwroot/Modules/Templates/External/Server/Services/[Module]Service.cs new file mode 100644 index 00000000..bc9ed6fe --- /dev/null +++ b/Oqtane.Server/wwwroot/Modules/Templates/External/Server/Services/[Module]Service.cs @@ -0,0 +1,101 @@ +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Http; +using Oqtane.Enums; +using Oqtane.Infrastructure; +using Oqtane.Models; +using Oqtane.Modules; +using Oqtane.Security; +using Oqtane.Shared; +using [Owner].Module.[Module].Repository; + +namespace [Owner].Module.[Module].Services +{ + public class Server[Module]Service : I[Module]Service, ITransientService + { + private readonly I[Module]Repository _[Module]Repository; + private readonly IUserPermissions _userPermissions; + private readonly ILogManager _logger; + private readonly IHttpContextAccessor _accessor; + private readonly Alias _alias; + + public Server[Module]Service(I[Module]Repository [Module]Repository, IUserPermissions userPermissions, ITenantManager tenantManager, ILogManager logger, IHttpContextAccessor accessor) + { + _[Module]Repository = [Module]Repository; + _userPermissions = userPermissions; + _logger = logger; + _accessor = accessor; + _alias = tenantManager.GetAlias(); + } + + public async Task> Get[Module]sAsync(int ModuleId) + { + if (_userPermissions.IsAuthorized(_accessor.HttpContext.User, _alias.SiteId, EntityNames.Module, ModuleId, PermissionNames.View)) + { + return (await _[Module]Repository.Get[Module]sAsync(ModuleId)).ToList(); + } + else + { + _logger.Log(LogLevel.Error, this, LogFunction.Security, "Unauthorized [Module] Get Attempt {ModuleId}", ModuleId); + return null; + } + } + + public async Task Get[Module]Async(int [Module]Id, int ModuleId) + { + if (_userPermissions.IsAuthorized(_accessor.HttpContext.User, _alias.SiteId, EntityNames.Module, ModuleId, PermissionNames.View)) + { + return await _[Module]Repository.Get[Module]Async([Module]Id); + } + else + { + _logger.Log(LogLevel.Error, this, LogFunction.Security, "Unauthorized [Module] Get Attempt {[Module]Id} {ModuleId}", [Module]Id, ModuleId); + return null; + } + } + + public async Task Add[Module]Async(Models.[Module] [Module]) + { + if (_userPermissions.IsAuthorized(_accessor.HttpContext.User, _alias.SiteId, EntityNames.Module, [Module].ModuleId, PermissionNames.Edit)) + { + [Module] = await _[Module]Repository.Add[Module]Async([Module]); + _logger.Log(LogLevel.Information, this, LogFunction.Create, "[Module] Added {[Module]}", [Module]); + } + else + { + _logger.Log(LogLevel.Error, this, LogFunction.Security, "Unauthorized [Module] Add Attempt {[Module]}", [Module]); + [Module] = null; + } + return [Module]; + } + + public async Task Update[Module]Async(Models.[Module] [Module]) + { + if (_userPermissions.IsAuthorized(_accessor.HttpContext.User, _alias.SiteId, EntityNames.Module, [Module].ModuleId, PermissionNames.Edit)) + { + [Module] = await _[Module]Repository.Update[Module]Async([Module]); + _logger.Log(LogLevel.Information, this, LogFunction.Update, "[Module] Updated {[Module]}", [Module]); + } + else + { + _logger.Log(LogLevel.Error, this, LogFunction.Security, "Unauthorized [Module] Update Attempt {[Module]}", [Module]); + [Module] = null; + } + return [Module]; + } + + public async Task Delete[Module]Async(int [Module]Id, int ModuleId) + { + if (_userPermissions.IsAuthorized(_accessor.HttpContext.User, _alias.SiteId, EntityNames.Module, ModuleId, PermissionNames.Edit)) + { + await _[Module]Repository.Delete[Module]Async([Module]Id); + _logger.Log(LogLevel.Information, this, LogFunction.Delete, "[Module] Deleted {[Module]Id}", [Module]Id); + } + else + { + _logger.Log(LogLevel.Error, this, LogFunction.Security, "Unauthorized [Module] Delete Attempt {[Module]Id} {ModuleId}", [Module]Id, ModuleId); + } + } + } +} diff --git a/Oqtane.Server/wwwroot/Modules/Templates/External/Server/Startup/[Module]ServerStartup.cs b/Oqtane.Server/wwwroot/Modules/Templates/External/Server/Startup/[Module]ServerStartup.cs index f2e55079..e5d1f16a 100644 --- a/Oqtane.Server/wwwroot/Modules/Templates/External/Server/Startup/[Module]ServerStartup.cs +++ b/Oqtane.Server/wwwroot/Modules/Templates/External/Server/Startup/[Module]ServerStartup.cs @@ -3,6 +3,7 @@ using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.DependencyInjection; using Oqtane.Infrastructure; using [Owner].Module.[Module].Repository; +using [Owner].Module.[Module].Services; namespace [Owner].Module.[Module].Startup { @@ -20,6 +21,7 @@ namespace [Owner].Module.[Module].Startup public void ConfigureServices(IServiceCollection services) { + services.AddTransient(); services.AddDbContextFactory<[Module]Context>(opt => { }, ServiceLifetime.Transient); } } diff --git a/Oqtane.Server/wwwroot/Modules/Templates/External/Client/Services/I[Module]Service.cs b/Oqtane.Server/wwwroot/Modules/Templates/External/Shared/Interfaces/I[Module]Service.cs similarity index 93% rename from Oqtane.Server/wwwroot/Modules/Templates/External/Client/Services/I[Module]Service.cs rename to Oqtane.Server/wwwroot/Modules/Templates/External/Shared/Interfaces/I[Module]Service.cs index 30ea62c9..8c75bf44 100644 --- a/Oqtane.Server/wwwroot/Modules/Templates/External/Client/Services/I[Module]Service.cs +++ b/Oqtane.Server/wwwroot/Modules/Templates/External/Shared/Interfaces/I[Module]Service.cs @@ -1,6 +1,5 @@ using System.Collections.Generic; using System.Threading.Tasks; -using [Owner].Module.[Module].Models; namespace [Owner].Module.[Module].Services {