commit
ed12194ea2
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -8,6 +8,8 @@ msbuild.binlog
|
|||
*.binlog
|
||||
*.nupkg
|
||||
|
||||
*.idea
|
||||
|
||||
Oqtane.Server/appsettings.json
|
||||
Oqtane.Server/Data/*.mdf
|
||||
Oqtane.Server/Data/*.ldf
|
||||
|
|
|
@ -36,7 +36,7 @@ else
|
|||
</select>
|
||||
</td>
|
||||
<td>
|
||||
<label>@Localizer["Rows:"] </label>
|
||||
<label>@Localizer["Maximum Records:"] </label>
|
||||
<select class="form-control" @onchange="(e => RowsChanged(e))">
|
||||
<option value="10">10</option>
|
||||
<option value="50">50</option>
|
||||
|
@ -48,7 +48,7 @@ else
|
|||
|
||||
@if (_logs.Any())
|
||||
{
|
||||
<Pager Items="@_logs">
|
||||
<Pager TableItem="Log" Items="@_logs">
|
||||
<Header>
|
||||
<th style="width: 1px;"> </th>
|
||||
<th>@Localizer["Date"]</th>
|
||||
|
@ -141,6 +141,10 @@ else
|
|||
private async Task GetLogs()
|
||||
{
|
||||
_logs = await LogService.GetLogsAsync(PageState.Site.SiteId, ((_level == "-") ? string.Empty : _level), ((_function == "-") ? string.Empty : _function), int.Parse(_rows));
|
||||
await InvokeAsync(() =>
|
||||
{
|
||||
base.StateHasChanged();
|
||||
});
|
||||
}
|
||||
|
||||
private string GetClass(string function)
|
||||
|
|
|
@ -31,6 +31,12 @@
|
|||
<td>@context.DeletedOn</td>
|
||||
</Row>
|
||||
</Pager>
|
||||
@if (_pages.Any())
|
||||
{
|
||||
<div style="text-align:right;">
|
||||
<ActionDialog Header="Delete All Pages" Message="@Localizer["Are You Sure You Wish To Permanently Delete All Pages?", "Delete All Pages"]" Action="Delete All Pages" Security="SecurityAccessLevel.Admin" Class="btn btn-danger" OnClick="@(async () => await DeleteAllPages())" ResourceKey="DeleteAllPages" />
|
||||
</div>
|
||||
}
|
||||
}
|
||||
</TabPanel>
|
||||
<TabPanel Name="Modules" ResourceKey="Modules">
|
||||
|
@ -59,6 +65,13 @@
|
|||
<td>@context.DeletedOn</td>
|
||||
</Row>
|
||||
</Pager>
|
||||
@if (_modules.Any())
|
||||
{
|
||||
<div style="text-align:right;">
|
||||
<ActionDialog Header="Delete All Modules" Message="@Localizer["Are You Sure You Wish To Permanently Delete All Modules?", "Delete All Modules"]" Action="Delete All Modules" Security="SecurityAccessLevel.Admin" Class="btn btn-danger" OnClick="@(async () => await DeleteAllModules())" ResourceKey="DeleteAllModules" />
|
||||
</div>
|
||||
}
|
||||
|
||||
}
|
||||
</TabPanel>
|
||||
</TabStrip>
|
||||
|
@ -126,6 +139,28 @@
|
|||
}
|
||||
}
|
||||
|
||||
private async Task DeleteAllPages()
|
||||
{
|
||||
try
|
||||
{
|
||||
foreach (Page page in _pages)
|
||||
{
|
||||
await PageService.DeletePageAsync(page.PageId);
|
||||
await logger.LogInformation("Page Permanently Deleted {Page}", page);
|
||||
}
|
||||
|
||||
await logger.LogInformation("Pages Permanently Deleted");
|
||||
await Load();
|
||||
StateHasChanged();
|
||||
NavigationManager.NavigateTo(NavigateUrl());
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
await logger.LogError(ex, "Error Permanently Deleting Pages {Error}", ex.Message);
|
||||
AddModuleMessage(ex.Message, MessageType.Error);
|
||||
}
|
||||
}
|
||||
|
||||
private async Task RestoreModule(Module module)
|
||||
{
|
||||
try
|
||||
|
@ -167,4 +202,31 @@
|
|||
AddModuleMessage(Localizer["Error Permanently Deleting Module"], MessageType.Error);
|
||||
}
|
||||
}
|
||||
|
||||
private async Task DeleteAllModules()
|
||||
{
|
||||
try
|
||||
{
|
||||
foreach (Module module in _modules)
|
||||
{
|
||||
await PageModuleService.DeletePageModuleAsync(module.PageModuleId);
|
||||
// check if there are any remaining module instances in the site
|
||||
_modules = await ModuleService.GetModulesAsync(PageState.Site.SiteId);
|
||||
|
||||
if (!_modules.Exists(item => item.ModuleId == module.ModuleId))
|
||||
{
|
||||
await ModuleService.DeleteModuleAsync(module.ModuleId);
|
||||
}
|
||||
}
|
||||
|
||||
await logger.LogInformation("Modules Permanently Deleted");
|
||||
await Load();
|
||||
StateHasChanged();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
await logger.LogError(ex, "Error Permanently Deleting Modules {Error}", ex.Message);
|
||||
AddModuleMessage(Localizer["Error Permanently Deleting Modules"], MessageType.Error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,15 +8,15 @@
|
|||
{
|
||||
if (childPage.PageId == PageState.Page.PageId)
|
||||
{
|
||||
<a class="dropdown-item active" href="@GetUrl(childPage)" target="@GetTarget(childPage)">
|
||||
<FontIcon Value="@childPage.Icon" />
|
||||
@childPage.Name <span class="sr-only">(current)</span>
|
||||
<a class="nav-link active px-3" href="@GetUrl(childPage)" target="@GetTarget(childPage)">
|
||||
<span class="@childPage.Icon" aria-hidden="true" />
|
||||
@childPage.Name <span class="sr-only">(current)</span>
|
||||
</a>
|
||||
}
|
||||
else
|
||||
{
|
||||
<a class="dropdown-item" href="@GetUrl(childPage)" target="@GetTarget(childPage)">
|
||||
<FontIcon Value="@childPage.Icon" />
|
||||
<a class="nav-link px-3" href="@GetUrl(childPage)" target="@GetTarget(childPage)">
|
||||
<span class="@childPage.Icon" aria-hidden="true" />
|
||||
@childPage.Name
|
||||
</a>
|
||||
}
|
||||
|
@ -34,7 +34,7 @@ else
|
|||
{
|
||||
<li class="nav-item active">
|
||||
<a class="nav-link" href="@GetUrl(childPage)" target="@GetTarget(childPage)">
|
||||
<FontIcon Value="@childPage.Icon" />
|
||||
<span class="@childPage.Icon" aria-hidden="true" />
|
||||
@childPage.Name <span class="sr-only">(current)</span>
|
||||
</a>
|
||||
</li>
|
||||
|
@ -43,7 +43,7 @@ else
|
|||
{
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="@GetUrl(childPage)" target="@GetTarget(childPage)">
|
||||
<FontIcon Value="@childPage.Icon" />
|
||||
<span class="@childPage.Icon" aria-hidden="true" />
|
||||
@childPage.Name
|
||||
</a>
|
||||
</li>
|
||||
|
@ -55,7 +55,7 @@ else
|
|||
{
|
||||
<li class="nav-item dropdown active">
|
||||
<a class="nav-link dropdown-toggle" href="@GetUrl(childPage)" target="@GetTarget(childPage)" id="@($"navbarDropdown{childPage.PageId}")" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
||||
<FontIcon Value="@childPage.Icon" />
|
||||
<span class="@childPage.Icon" aria-hidden="true" />
|
||||
@childPage.Name <span class="sr-only">(current)</span>
|
||||
</a>
|
||||
<MenuItemsHorizontal ParentPage="childPage" Pages="Pages" />
|
||||
|
@ -65,7 +65,7 @@ else
|
|||
{
|
||||
<li class="nav-item dropdown">
|
||||
<a class="nav-link dropdown-toggle" href="@GetUrl(childPage)" target="@GetTarget(childPage)" id="@($"navbarDropdown{childPage.PageId}")" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
||||
<FontIcon Value="@childPage.Icon" />
|
||||
<span class="@childPage.Icon" aria-hidden="true" />
|
||||
@childPage.Name
|
||||
</a>
|
||||
<MenuItemsHorizontal ParentPage="childPage" Pages="Pages" />
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
{
|
||||
<li class="nav-item px-3" style="margin-left: @(childPage.Level * 15)px;">
|
||||
<a class="nav-link active" href="@GetUrl(childPage)" target="@GetTarget(childPage)">
|
||||
<FontIcon Value="@childPage.Icon" />
|
||||
<span class="@childPage.Icon" aria-hidden="true" />
|
||||
@childPage.Name <span class="sr-only">(current)</span>
|
||||
</a>
|
||||
</li>
|
||||
|
@ -18,7 +18,7 @@
|
|||
{
|
||||
<li class="nav-item px-3" style="margin-left: @(childPage.Level * 15)px;">
|
||||
<a class="nav-link" href="@GetUrl(childPage)" target="@GetTarget(childPage)">
|
||||
<FontIcon Value="@childPage.Icon" />
|
||||
<span class="@childPage.Icon" aria-hidden="true" />
|
||||
@childPage.Name
|
||||
</a>
|
||||
</li>
|
||||
|
@ -38,7 +38,7 @@ else
|
|||
{
|
||||
<li class="nav-item px-3" style="margin-left: @(childPage.Level * 15)px;">
|
||||
<a class="nav-link active" href="@GetUrl(childPage)" target="@GetTarget(childPage)">
|
||||
<FontIcon Value="@childPage.Icon" />
|
||||
<span class="@childPage.Icon" aria-hidden="true" />
|
||||
@childPage.Name <span class="sr-only">(current)</span>
|
||||
</a>
|
||||
</li>
|
||||
|
@ -47,7 +47,7 @@ else
|
|||
{
|
||||
<li class="nav-item px-3" style="margin-left: @(childPage.Level * 15)px;">
|
||||
<a class="nav-link" href="@GetUrl(childPage)" target="@GetTarget(childPage)">
|
||||
<FontIcon Value="@childPage.Icon" />
|
||||
<span class="@childPage.Icon" aria-hidden="true" />
|
||||
@childPage.Name
|
||||
</a>
|
||||
</li>
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
using System.Diagnostics.CodeAnalysis;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace Oqtane.Extensions
|
||||
{
|
||||
public static class DbContextOptionsBuilderExtensions
|
||||
{
|
||||
public static DbContextOptionsBuilder UseOqtaneDatabase([NotNull] this DbContextOptionsBuilder optionsBuilder, string connectionString)
|
||||
{
|
||||
optionsBuilder.UseSqlServer(connectionString);
|
||||
|
||||
return optionsBuilder;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -168,9 +168,10 @@ namespace Oqtane.Infrastructure
|
|||
var dataDirectory = AppDomain.CurrentDomain.GetData("DataDirectory")?.ToString();
|
||||
if (!Directory.Exists(dataDirectory)) Directory.CreateDirectory(dataDirectory);
|
||||
|
||||
using (var dbc = new DbContext(new DbContextOptionsBuilder().UseSqlServer(NormalizeConnectionString(install.ConnectionString)).Options))
|
||||
var connectionString = NormalizeConnectionString(install.ConnectionString);
|
||||
using (var dbc = new DbContext(new DbContextOptionsBuilder().UseOqtaneDatabase(connectionString).Options))
|
||||
{
|
||||
// create empty database if it does not exist
|
||||
// create empty database if it does not exist
|
||||
dbc.Database.EnsureCreated();
|
||||
result.Success = true;
|
||||
}
|
||||
|
@ -235,7 +236,7 @@ namespace Oqtane.Infrastructure
|
|||
|
||||
if (!string.IsNullOrEmpty(install.TenantName) && !string.IsNullOrEmpty(install.Aliases))
|
||||
{
|
||||
using (var db = new InstallationContext(NormalizeConnectionString(_config.GetConnectionString(SettingKeys.ConnectionStringKey))))
|
||||
using (var db = new InstallationContext(NormalizeConnectionString(_config.GetConnectionString(SettingKeys.ConnectionStringKey))))
|
||||
{
|
||||
Tenant tenant;
|
||||
if (install.IsNewTenant)
|
||||
|
@ -274,7 +275,7 @@ namespace Oqtane.Infrastructure
|
|||
using (var scope = _serviceScopeFactory.CreateScope())
|
||||
{
|
||||
var upgrades = scope.ServiceProvider.GetRequiredService<IUpgradeManager>();
|
||||
|
||||
|
||||
using (var db = new InstallationContext(NormalizeConnectionString(_config.GetConnectionString(SettingKeys.ConnectionStringKey))))
|
||||
{
|
||||
foreach (var tenant in db.Tenant.ToList())
|
||||
|
|
|
@ -4,11 +4,12 @@ using Microsoft.AspNetCore.Http;
|
|||
using Microsoft.AspNetCore.Identity;
|
||||
using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Oqtane.Extensions;
|
||||
using Oqtane.Models;
|
||||
|
||||
namespace Oqtane.Repository
|
||||
{
|
||||
public class DBContextBase : IdentityUserContext<IdentityUser>
|
||||
public class DBContextBase : IdentityUserContext<IdentityUser>
|
||||
{
|
||||
private ITenantResolver _tenantResolver;
|
||||
private IHttpContextAccessor _accessor;
|
||||
|
@ -24,63 +25,16 @@ namespace Oqtane.Repository
|
|||
var tenant = _tenantResolver.GetTenant();
|
||||
if (tenant != null)
|
||||
{
|
||||
optionsBuilder.UseSqlServer(tenant.DBConnectionString
|
||||
.Replace("|DataDirectory|", AppDomain.CurrentDomain.GetData("DataDirectory")?.ToString())
|
||||
);
|
||||
var connectionString = tenant.DBConnectionString
|
||||
.Replace("|DataDirectory|", AppDomain.CurrentDomain.GetData("DataDirectory")?.ToString());
|
||||
optionsBuilder.UseOqtaneDatabase(connectionString);
|
||||
}
|
||||
base.OnConfiguring(optionsBuilder);
|
||||
}
|
||||
|
||||
public override int SaveChanges()
|
||||
{
|
||||
ChangeTracker.DetectChanges();
|
||||
|
||||
string username = "";
|
||||
if (_accessor.HttpContext != null && _accessor.HttpContext.User.Identity.Name != null)
|
||||
{
|
||||
username = _accessor.HttpContext.User.Identity.Name;
|
||||
}
|
||||
DateTime date = DateTime.UtcNow;
|
||||
|
||||
var created = ChangeTracker.Entries()
|
||||
.Where(x => x.State == EntityState.Added);
|
||||
|
||||
foreach(var item in created)
|
||||
{
|
||||
if (item.Entity is IAuditable)
|
||||
{
|
||||
item.CurrentValues[nameof(IAuditable.CreatedBy)] = username;
|
||||
item.CurrentValues[nameof(IAuditable.CreatedOn)] = date;
|
||||
}
|
||||
}
|
||||
|
||||
var modified = ChangeTracker.Entries()
|
||||
.Where(x => x.State == EntityState.Modified || x.State == EntityState.Added);
|
||||
|
||||
foreach (var item in modified)
|
||||
{
|
||||
if (item.Entity is IAuditable)
|
||||
{
|
||||
item.CurrentValues[nameof(IAuditable.ModifiedBy)] = username;
|
||||
item.CurrentValues[nameof(IAuditable.ModifiedOn)] = date;
|
||||
}
|
||||
|
||||
if (item.Entity is IDeletable && item.State != EntityState.Added)
|
||||
{
|
||||
if ((bool)item.CurrentValues[nameof(IDeletable.IsDeleted)]
|
||||
&& !item.GetDatabaseValues().GetValue<bool>(nameof(IDeletable.IsDeleted)))
|
||||
{
|
||||
item.CurrentValues[nameof(IDeletable.DeletedBy)] = username;
|
||||
item.CurrentValues[nameof(IDeletable.DeletedOn)] = date;
|
||||
}
|
||||
else if (!(bool)item.CurrentValues[nameof(IDeletable.IsDeleted)]
|
||||
&& item.GetDatabaseValues().GetValue<bool>(nameof(IDeletable.IsDeleted)))
|
||||
{
|
||||
item.CurrentValues[nameof(IDeletable.DeletedBy)] = null;
|
||||
item.CurrentValues[nameof(IDeletable.DeletedOn)] = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
DbContextUtils.SaveChanges(this, _accessor);
|
||||
|
||||
return base.SaveChanges();
|
||||
}
|
||||
|
|
65
Oqtane.Server/Repository/Context/DbContextUtils.cs
Normal file
65
Oqtane.Server/Repository/Context/DbContextUtils.cs
Normal file
|
@ -0,0 +1,65 @@
|
|||
using System;
|
||||
using System.Linq;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Oqtane.Models;
|
||||
|
||||
namespace Oqtane.Repository
|
||||
{
|
||||
public class DbContextUtils
|
||||
{
|
||||
public static void SaveChanges(DbContext context, IHttpContextAccessor accessor)
|
||||
{
|
||||
var changeTracker = context.ChangeTracker;
|
||||
|
||||
changeTracker.DetectChanges();
|
||||
|
||||
string username = "";
|
||||
if (accessor.HttpContext != null && accessor.HttpContext.User.Identity.Name != null)
|
||||
{
|
||||
username = accessor.HttpContext.User.Identity.Name;
|
||||
}
|
||||
DateTime date = DateTime.UtcNow;
|
||||
|
||||
var created = changeTracker.Entries()
|
||||
.Where(x => x.State == EntityState.Added);
|
||||
|
||||
foreach(var item in created)
|
||||
{
|
||||
if (item.Entity is IAuditable)
|
||||
{
|
||||
item.CurrentValues[nameof(IAuditable.CreatedBy)] = username;
|
||||
item.CurrentValues[nameof(IAuditable.CreatedOn)] = date;
|
||||
}
|
||||
}
|
||||
|
||||
var modified = changeTracker.Entries()
|
||||
.Where(x => x.State == EntityState.Modified || x.State == EntityState.Added);
|
||||
|
||||
foreach (var item in modified)
|
||||
{
|
||||
if (item.Entity is IAuditable)
|
||||
{
|
||||
item.CurrentValues[nameof(IAuditable.ModifiedBy)] = username;
|
||||
item.CurrentValues[nameof(IAuditable.ModifiedOn)] = date;
|
||||
}
|
||||
|
||||
if (item.Entity is IDeletable && item.State != EntityState.Added)
|
||||
{
|
||||
if ((bool)item.CurrentValues[nameof(IDeletable.IsDeleted)]
|
||||
&& !item.GetDatabaseValues().GetValue<bool>(nameof(IDeletable.IsDeleted)))
|
||||
{
|
||||
item.CurrentValues[nameof(IDeletable.DeletedBy)] = username;
|
||||
item.CurrentValues[nameof(IDeletable.DeletedOn)] = date;
|
||||
}
|
||||
else if (!(bool)item.CurrentValues[nameof(IDeletable.IsDeleted)]
|
||||
&& item.GetDatabaseValues().GetValue<bool>(nameof(IDeletable.IsDeleted)))
|
||||
{
|
||||
item.CurrentValues[nameof(IDeletable.DeletedBy)] = null;
|
||||
item.CurrentValues[nameof(IDeletable.DeletedOn)] = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,10 +1,11 @@
|
|||
using System.Diagnostics.CodeAnalysis;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Oqtane.Extensions;
|
||||
using Oqtane.Models;
|
||||
|
||||
namespace Oqtane.Repository
|
||||
{
|
||||
|
||||
|
||||
public class InstallationContext : DbContext
|
||||
{
|
||||
private readonly string _connectionString;
|
||||
|
@ -15,7 +16,7 @@ namespace Oqtane.Repository
|
|||
}
|
||||
|
||||
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
|
||||
=> optionsBuilder.UseSqlServer(_connectionString);
|
||||
=> optionsBuilder.UseOqtaneDatabase(_connectionString);
|
||||
|
||||
public virtual DbSet<Alias> Alias { get; set; }
|
||||
public virtual DbSet<Tenant> Tenant { get; set; }
|
||||
|
|
|
@ -4,13 +4,14 @@ using Microsoft.AspNetCore.Http;
|
|||
using Microsoft.EntityFrameworkCore;
|
||||
using Oqtane.Models;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Oqtane.Extensions;
|
||||
|
||||
namespace Oqtane.Repository
|
||||
{
|
||||
public class MasterDBContext : DbContext
|
||||
{
|
||||
private IHttpContextAccessor _accessor;
|
||||
private IConfiguration _configuration;
|
||||
private readonly IHttpContextAccessor _accessor;
|
||||
private readonly IConfiguration _configuration;
|
||||
|
||||
public MasterDBContext(DbContextOptions<MasterDBContext> options, IHttpContextAccessor accessor, IConfiguration configuration) : base(options)
|
||||
{
|
||||
|
@ -20,11 +21,12 @@ namespace Oqtane.Repository
|
|||
|
||||
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(_configuration.GetConnectionString("DefaultConnection")))
|
||||
if (!String.IsNullOrEmpty(_configuration.GetConnectionString("DefaultConnection")))
|
||||
{
|
||||
optionsBuilder.UseSqlServer(_configuration.GetConnectionString("DefaultConnection")
|
||||
.Replace("|DataDirectory|", AppDomain.CurrentDomain.GetData("DataDirectory")?.ToString())
|
||||
);
|
||||
var connectionString = _configuration.GetConnectionString("DefaultConnection")
|
||||
.Replace("|DataDirectory|", AppDomain.CurrentDomain.GetData("DataDirectory")?.ToString());
|
||||
|
||||
optionsBuilder.UseOqtaneDatabase(connectionString);
|
||||
}
|
||||
base.OnConfiguring(optionsBuilder);
|
||||
}
|
||||
|
@ -37,38 +39,7 @@ namespace Oqtane.Repository
|
|||
|
||||
public override int SaveChanges()
|
||||
{
|
||||
ChangeTracker.DetectChanges();
|
||||
|
||||
string username = "";
|
||||
if (_accessor.HttpContext != null && _accessor.HttpContext.User.Identity.Name != null)
|
||||
{
|
||||
username = _accessor.HttpContext.User.Identity.Name;
|
||||
}
|
||||
DateTime date = DateTime.UtcNow;
|
||||
|
||||
var created = ChangeTracker.Entries()
|
||||
.Where(x => x.State == EntityState.Added);
|
||||
|
||||
foreach (var item in created)
|
||||
{
|
||||
if (item.Entity is IAuditable)
|
||||
{
|
||||
item.CurrentValues[nameof(IAuditable.CreatedBy)] = username;
|
||||
item.CurrentValues[nameof(IAuditable.CreatedOn)] = date;
|
||||
}
|
||||
}
|
||||
|
||||
var modified = ChangeTracker.Entries()
|
||||
.Where(x => x.State == EntityState.Modified || x.State == EntityState.Added);
|
||||
|
||||
foreach (var item in modified)
|
||||
{
|
||||
if (item.Entity is IAuditable)
|
||||
{
|
||||
item.CurrentValues[nameof(IAuditable.ModifiedBy)] = username;
|
||||
item.CurrentValues[nameof(IAuditable.ModifiedOn)] = date;
|
||||
}
|
||||
}
|
||||
DbContextUtils.SaveChanges(this, _accessor);
|
||||
|
||||
return base.SaveChanges();
|
||||
}
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net5.0</TargetFramework>
|
||||
<LangVersion>7.3</LangVersion>
|
||||
<AddRazorSupportForMvc>true</AddRazorSupportForMvc>
|
||||
<Version>1.0.0</Version>
|
||||
<Product>[Owner].[Module]</Product>
|
||||
|
|
|
@ -16,6 +16,8 @@ EndProject
|
|||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{77EECA8C-B58E-469E-B8C5-D543AFC9A654}"
|
||||
ProjectSection(SolutionItems) = preProject
|
||||
.editorconfig = .editorconfig
|
||||
.gitignore = .gitignore
|
||||
README.md = README.md
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Global
|
||||
|
|
|
@ -50,9 +50,11 @@ There is a separate [Documentation repository](https://github.com/oqtane/oqtane.
|
|||
This project is a work in progress and the schedule for implementing enhancements is dependent upon the availability of community members who are willing/able to assist.
|
||||
|
||||
V.2.1.0 ( Q1 2021 )
|
||||
- [ ] Cross Platform Database Support ( ie. SQLite ) - see [#964](https://github.com/oqtane/oqtane.framework/discussions/964)
|
||||
- [ ] EF Core Migrations for Database Installation/Upgrade - see [#964](https://github.com/oqtane/oqtane.framework/discussions/964)
|
||||
|
||||
V.2.0.1 ( Feb 27, 2021 )
|
||||
- [x] Complete Static Localization of Admin UI
|
||||
- [ ] Cross Platform Database Support ( ie. SQLite )
|
||||
- [ ] EF Core Migrations for Database Installation/Upgrade
|
||||
|
||||
V.2.0.0 ( released in conjuntion with .NET 5 on Nov 11, 2020 )
|
||||
- [x] Migration to .NET 5
|
||||
|
|
Loading…
Reference in New Issue
Block a user