performance and user experience improvements
This commit is contained in:
@ -101,13 +101,12 @@ namespace Oqtane.Controllers
|
||||
public void Delete(int id, int siteid)
|
||||
{
|
||||
ModuleDefinition moduledefinition = _moduleDefinitions.GetModuleDefinition(id, siteid);
|
||||
if (moduledefinition != null )
|
||||
if (moduledefinition != null && Utilities.GetAssemblyName(moduledefinition.ServerManagerType) != "Oqtane.Server")
|
||||
{
|
||||
if (!string.IsNullOrEmpty(moduledefinition.ServerManagerType) && Utilities.GetAssemblyName(moduledefinition.ServerManagerType) != "Oqtane.Server")
|
||||
// execute uninstall logic or scripts
|
||||
if (!string.IsNullOrEmpty(moduledefinition.ServerManagerType))
|
||||
{
|
||||
Type moduletype = Type.GetType(moduledefinition.ServerManagerType);
|
||||
|
||||
// execute uninstall logic
|
||||
foreach (Tenant tenant in _tenants.GetTenants())
|
||||
{
|
||||
try
|
||||
@ -128,34 +127,45 @@ namespace Oqtane.Controllers
|
||||
_logger.Log(LogLevel.Error, this, LogFunction.Delete, "Error Uninstalling {ModuleDefinitionName} For Tenant {Tenant} {Error}", moduledefinition.ModuleDefinitionName, tenant.Name, ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
// use assets.json to clean up file resources
|
||||
string assetfilepath = Path.Combine(_environment.WebRootPath, "Modules", Utilities.GetTypeName(moduledefinition.ModuleDefinitionName), "assets.json");
|
||||
if (System.IO.File.Exists(assetfilepath))
|
||||
{
|
||||
List<string> assets = JsonSerializer.Deserialize<List<string>>(System.IO.File.ReadAllText(assetfilepath));
|
||||
foreach(string asset in assets)
|
||||
{
|
||||
if (System.IO.File.Exists(asset))
|
||||
{
|
||||
System.IO.File.Delete(asset);
|
||||
}
|
||||
}
|
||||
_logger.Log(LogLevel.Information, this, LogFunction.Delete, "Module Assets Removed For {ModuleDefinitionName}", moduledefinition.ModuleDefinitionName);
|
||||
}
|
||||
|
||||
// clean up module static resource folder
|
||||
string folder = Path.Combine(_environment.WebRootPath, Path.Combine("Modules", Utilities.GetTypeName(moduledefinition.ModuleDefinitionName)));
|
||||
if (Directory.Exists(folder))
|
||||
{
|
||||
Directory.Delete(folder, true);
|
||||
_logger.Log(LogLevel.Information, this, LogFunction.Delete, "Module Resources Folder Removed For {ModuleDefinitionName}", moduledefinition.ModuleDefinitionName);
|
||||
}
|
||||
|
||||
// remove module definition
|
||||
_moduleDefinitions.DeleteModuleDefinition(id, siteid);
|
||||
_logger.Log(LogLevel.Information, this, LogFunction.Delete, "Module Definition {ModuleDefinitionName} Deleted", moduledefinition.Name);
|
||||
}
|
||||
|
||||
// remove module assets
|
||||
string assetpath = Path.Combine(_environment.WebRootPath, "Modules", Utilities.GetTypeName(moduledefinition.ModuleDefinitionName));
|
||||
if (System.IO.File.Exists(Path.Combine(assetpath, "assets.json")))
|
||||
{
|
||||
// use assets.json to clean up file resources
|
||||
List<string> assets = JsonSerializer.Deserialize<List<string>>(System.IO.File.ReadAllText(Path.Combine(assetpath, "assets.json")));
|
||||
foreach(string asset in assets)
|
||||
{
|
||||
// legacy support for assets that were stored as absolute paths
|
||||
string filepath = asset.StartsWith("\\") ? Path.Combine(_environment.ContentRootPath, asset.Substring(1)) : asset;
|
||||
if (System.IO.File.Exists(filepath))
|
||||
{
|
||||
System.IO.File.Delete(filepath);
|
||||
}
|
||||
}
|
||||
_logger.Log(LogLevel.Information, this, LogFunction.Delete, "Module Assets Removed For {ModuleDefinitionName}", moduledefinition.ModuleDefinitionName);
|
||||
}
|
||||
else
|
||||
{
|
||||
// attempt to delete assemblies based on naming convention
|
||||
foreach(string asset in Directory.GetFiles(Path.GetDirectoryName(Assembly.GetEntryAssembly().Location), Utilities.GetTypeName(moduledefinition.ModuleDefinitionName) + "*.*"))
|
||||
{
|
||||
System.IO.File.Delete(asset);
|
||||
}
|
||||
_logger.Log(LogLevel.Warning, this, LogFunction.Delete, "Module Assets Removed For {ModuleDefinitionName}. Please Note That Some Assets May Have Been Missed Due To A Missing Asset Manifest. An Asset Manifest Is Only Created If A Module Is Installed From A Nuget Package.", moduledefinition.Name);
|
||||
}
|
||||
|
||||
// clean up module static resource folder
|
||||
if (Directory.Exists(assetpath))
|
||||
{
|
||||
Directory.Delete(assetpath, true);
|
||||
_logger.Log(LogLevel.Information, this, LogFunction.Delete, "Module Static Resources Folder Removed For {ModuleDefinitionName}", moduledefinition.ModuleDefinitionName);
|
||||
}
|
||||
|
||||
// remove module definition
|
||||
_moduleDefinitions.DeleteModuleDefinition(id);
|
||||
_logger.Log(LogLevel.Information, this, LogFunction.Delete, "Module Definition {ModuleDefinitionName} Deleted", moduledefinition.Name);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -57,28 +57,44 @@ namespace Oqtane.Controllers
|
||||
Theme theme = themes.Where(item => item.ThemeName == themename).FirstOrDefault();
|
||||
if (theme != null && Utilities.GetAssemblyName(theme.ThemeName) != "Oqtane.Client")
|
||||
{
|
||||
// use assets.json to clean up file resources
|
||||
string assetfilepath = Path.Combine(_environment.WebRootPath, "Themes", Utilities.GetTypeName(theme.ThemeName), "assets.json");
|
||||
if (System.IO.File.Exists(assetfilepath))
|
||||
// remove theme assets
|
||||
string assetpath = Path.Combine(_environment.WebRootPath, "Themes", Utilities.GetTypeName(theme.ThemeName));
|
||||
if (System.IO.File.Exists(Path.Combine(assetpath, "assets.json")))
|
||||
{
|
||||
List<string> assets = JsonSerializer.Deserialize<List<string>>(System.IO.File.ReadAllText(assetfilepath));
|
||||
// use assets.json to clean up file resources
|
||||
List<string> assets = JsonSerializer.Deserialize<List<string>>(System.IO.File.ReadAllText(Path.Combine(assetpath, "assets.json")));
|
||||
foreach (string asset in assets)
|
||||
{
|
||||
if (System.IO.File.Exists(asset))
|
||||
// legacy support for assets that were stored as absolute paths
|
||||
string filepath = (asset.StartsWith("\\")) ? Path.Combine(_environment.ContentRootPath, asset.Substring(1)) : asset;
|
||||
if (System.IO.File.Exists(filepath))
|
||||
{
|
||||
System.IO.File.Delete(asset);
|
||||
System.IO.File.Delete(filepath);
|
||||
}
|
||||
}
|
||||
_logger.Log(LogLevel.Information, this, LogFunction.Delete, "Theme Assets Removed For {ThemeName}", theme.ThemeName);
|
||||
}
|
||||
else
|
||||
{
|
||||
// attempt to delete assemblies based on naming convention
|
||||
foreach (string asset in Directory.GetFiles(Path.GetDirectoryName(Assembly.GetEntryAssembly().Location), Utilities.GetTypeName(theme.ThemeName) + "*.*"))
|
||||
{
|
||||
System.IO.File.Delete(asset);
|
||||
}
|
||||
_logger.Log(LogLevel.Warning, this, LogFunction.Delete, "Theme Assets Removed For {ThemeName}. Please Note That Some Assets May Have Been Missed Due To A Missing Asset Manifest. An Asset Manifest Is Only Created If A Theme Is Installed From A Nuget Package.", theme.ThemeName);
|
||||
}
|
||||
|
||||
// clean up theme static resource folder
|
||||
string folder = Path.Combine(_environment.WebRootPath, "Themes" , Utilities.GetTypeName(theme.ThemeName));
|
||||
if (Directory.Exists(folder))
|
||||
{
|
||||
Directory.Delete(folder, true);
|
||||
_logger.Log(LogLevel.Information, this, LogFunction.Delete, "Theme Resource Folder Removed For {ThemeName}", theme.ThemeName);
|
||||
_logger.Log(LogLevel.Information, this, LogFunction.Delete, "Theme Static Resource Folder Removed For {ThemeName}", theme.ThemeName);
|
||||
}
|
||||
|
||||
// remove theme
|
||||
_themes.DeleteTheme(theme.ThemeName);
|
||||
_logger.Log(LogLevel.Information, this, LogFunction.Delete, "Theme Removed For {ThemeName}", theme.ThemeName);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -28,13 +28,13 @@ namespace Oqtane.Infrastructure
|
||||
|
||||
public void InstallPackages(string folders)
|
||||
{
|
||||
if (!InstallPackages(folders, _environment.WebRootPath))
|
||||
if (!InstallPackages(folders, _environment.WebRootPath, _environment.ContentRootPath))
|
||||
{
|
||||
// error installing packages
|
||||
}
|
||||
}
|
||||
|
||||
public static bool InstallPackages(string folders, string webRootPath)
|
||||
public static bool InstallPackages(string folders, string webRootPath, string contentRootPath)
|
||||
{
|
||||
bool install = false;
|
||||
string binFolder = Path.GetDirectoryName(Assembly.GetEntryAssembly()?.Location);
|
||||
@ -79,6 +79,7 @@ namespace Oqtane.Infrastructure
|
||||
if (frameworkversion == "" || Version.Parse(Constants.Version).CompareTo(Version.Parse(frameworkversion)) >= 0)
|
||||
{
|
||||
List<string> assets = new List<string>();
|
||||
bool manifest = false;
|
||||
|
||||
// module and theme packages must be in form of name.1.0.0.nupkg
|
||||
string name = Path.GetFileNameWithoutExtension(packagename);
|
||||
@ -91,36 +92,41 @@ namespace Oqtane.Infrastructure
|
||||
string foldername = Path.GetDirectoryName(entry.FullName).Split(Path.DirectorySeparatorChar)[0];
|
||||
string filename = Path.GetFileName(entry.FullName);
|
||||
|
||||
if (!manifest && filename == "assets.json")
|
||||
{
|
||||
manifest = true;
|
||||
}
|
||||
|
||||
switch (foldername)
|
||||
{
|
||||
case "lib":
|
||||
filename = Path.Combine(binFolder, filename);
|
||||
ExtractFile(entry, filename);
|
||||
assets.Add(filename);
|
||||
assets.Add(filename.Replace(contentRootPath, ""));
|
||||
break;
|
||||
case "wwwroot":
|
||||
filename = Path.Combine(webRootPath, Utilities.PathCombine(entry.FullName.Replace("wwwroot/", "").Split('/')));
|
||||
ExtractFile(entry, filename);
|
||||
assets.Add(filename);
|
||||
assets.Add(filename.Replace(contentRootPath, ""));
|
||||
break;
|
||||
case "runtimes":
|
||||
var destSubFolder = Path.GetDirectoryName(entry.FullName);
|
||||
filename = Path.Combine(binFolder, destSubFolder, filename);
|
||||
ExtractFile(entry, filename);
|
||||
assets.Add(filename);
|
||||
assets.Add(filename.Replace(contentRootPath, ""));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// save list of assets
|
||||
if (assets.Count != 0)
|
||||
// save dynamic list of assets
|
||||
if (!manifest && assets.Count != 0)
|
||||
{
|
||||
string assetfilepath = Path.Combine(webRootPath, folder, name, "assets.json");
|
||||
if (File.Exists(assetfilepath))
|
||||
string manifestpath = Path.Combine(webRootPath, folder, name, "assets.json");
|
||||
if (File.Exists(manifestpath))
|
||||
{
|
||||
File.Delete(assetfilepath);
|
||||
File.Delete(manifestpath);
|
||||
}
|
||||
File.WriteAllText(assetfilepath, JsonSerializer.Serialize(assets));
|
||||
File.WriteAllText(manifestpath, JsonSerializer.Serialize(assets));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -181,7 +181,7 @@ namespace Oqtane.Infrastructure
|
||||
}
|
||||
else
|
||||
{
|
||||
// auto registration
|
||||
// auto registration - does not run on initial installation but will run after restart
|
||||
job = new Job { JobType = jobTypeName };
|
||||
// optional properties
|
||||
var jobType = Type.GetType(jobTypeName);
|
||||
|
@ -36,6 +36,7 @@
|
||||
<EmbeddedResource Include="Scripts\Tenant.02.00.00.01.sql" />
|
||||
<EmbeddedResource Include="Scripts\Tenant.02.00.01.01.sql" />
|
||||
<EmbeddedResource Include="Scripts\Tenant.02.00.01.02.sql" />
|
||||
<EmbeddedResource Include="Scripts\Tenant.02.00.01.03.sql" />
|
||||
<EmbeddedResource Include="Modules\HtmlText\Scripts\HtmlText.1.0.0.sql" />
|
||||
<EmbeddedResource Include="Modules\HtmlText\Scripts\HtmlText.Uninstall.sql" />
|
||||
</ItemGroup>
|
||||
|
@ -42,8 +42,8 @@ namespace Oqtane.Pages
|
||||
ProcessThemeControls(assembly);
|
||||
}
|
||||
|
||||
// if framework is installed
|
||||
if (!string.IsNullOrEmpty(_configuration.GetConnectionString("DefaultConnection")))
|
||||
// if culture not specified and framework is installed
|
||||
if (HttpContext.Request.Cookies[CookieRequestCultureProvider.DefaultCookieName] == null && !string.IsNullOrEmpty(_configuration.GetConnectionString("DefaultConnection")))
|
||||
{
|
||||
Uri uri = new Uri(Request.GetDisplayUrl());
|
||||
var alias = _aliases.GetAlias(uri.Authority + "/" + uri.LocalPath.Substring(1));
|
||||
@ -58,6 +58,13 @@ namespace Oqtane.Pages
|
||||
CookieRequestCultureProvider.MakeCookieValue(
|
||||
new RequestCulture(language.Code)));
|
||||
}
|
||||
else
|
||||
{
|
||||
HttpContext.Response.Cookies.Append(
|
||||
CookieRequestCultureProvider.DefaultCookieName,
|
||||
CookieRequestCultureProvider.MakeCookieValue(
|
||||
new RequestCulture(_configuration.GetSection("Localization").GetValue("DefaultCulture", Constants.DefaultCulture))));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Generic;
|
||||
using Oqtane.Models;
|
||||
|
||||
namespace Oqtane.Repository
|
||||
@ -9,6 +9,6 @@ namespace Oqtane.Repository
|
||||
IEnumerable<ModuleDefinition> GetModuleDefinitions(int sideId);
|
||||
ModuleDefinition GetModuleDefinition(int moduleDefinitionId, int sideId);
|
||||
void UpdateModuleDefinition(ModuleDefinition moduleDefinition);
|
||||
void DeleteModuleDefinition(int moduleDefinitionId, int siteId);
|
||||
void DeleteModuleDefinition(int moduleDefinitionId);
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Generic;
|
||||
using Oqtane.Models;
|
||||
|
||||
namespace Oqtane.Repository
|
||||
@ -6,5 +6,6 @@ namespace Oqtane.Repository
|
||||
public interface IThemeRepository
|
||||
{
|
||||
IEnumerable<Theme> GetThemes();
|
||||
void DeleteTheme(string ThemeName);
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
@ -16,7 +17,6 @@ namespace Oqtane.Repository
|
||||
private MasterDBContext _db;
|
||||
private readonly IMemoryCache _cache;
|
||||
private readonly IPermissionRepository _permissions;
|
||||
private List<ModuleDefinition> _moduleDefinitions; // lazy load
|
||||
|
||||
public ModuleDefinitionRepository(MasterDBContext context, IMemoryCache cache, IPermissionRepository permissions)
|
||||
{
|
||||
@ -46,44 +46,71 @@ namespace Oqtane.Repository
|
||||
_db.Entry(moduleDefinition).State = EntityState.Modified;
|
||||
_db.SaveChanges();
|
||||
_permissions.UpdatePermissions(moduleDefinition.SiteId, EntityNames.ModuleDefinition, moduleDefinition.ModuleDefinitionId, moduleDefinition.Permissions);
|
||||
_cache.Remove("moduledefinitions:" + moduleDefinition.SiteId.ToString());
|
||||
}
|
||||
|
||||
public void DeleteModuleDefinition(int moduleDefinitionId, int siteId)
|
||||
public void DeleteModuleDefinition(int moduleDefinitionId)
|
||||
{
|
||||
ModuleDefinition moduleDefinition = _db.ModuleDefinition.Find(moduleDefinitionId);
|
||||
_permissions.DeletePermissions(siteId, EntityNames.ModuleDefinition, moduleDefinitionId);
|
||||
_db.ModuleDefinition.Remove(moduleDefinition);
|
||||
_db.SaveChanges();
|
||||
_cache.Remove("moduledefinitions");
|
||||
}
|
||||
|
||||
public List<ModuleDefinition> LoadModuleDefinitions(int siteId)
|
||||
{
|
||||
// get module definitions for site
|
||||
List<ModuleDefinition> moduleDefinitions = _cache.GetOrCreate("moduledefinitions:" + siteId.ToString(), entry =>
|
||||
// get module definitions
|
||||
List<ModuleDefinition> moduleDefinitions;
|
||||
if (siteId != -1)
|
||||
{
|
||||
entry.SlidingExpiration = TimeSpan.FromMinutes(30);
|
||||
return LoadSiteModuleDefinitions(siteId);
|
||||
});
|
||||
moduleDefinitions = _cache.GetOrCreate("moduledefinitions", entry =>
|
||||
{
|
||||
entry.SlidingExpiration = TimeSpan.FromMinutes(30);
|
||||
return LoadModuleDefinitions();
|
||||
});
|
||||
|
||||
// get all module definition permissions for site
|
||||
List<Permission> permissions = _permissions.GetPermissions(siteId, EntityNames.ModuleDefinition).ToList();
|
||||
|
||||
// populate module definition permissions
|
||||
foreach (ModuleDefinition moduledefinition in moduleDefinitions)
|
||||
{
|
||||
moduledefinition.SiteId = siteId;
|
||||
if (permissions.Count == 0)
|
||||
{
|
||||
_permissions.UpdatePermissions(siteId, EntityNames.ModuleDefinition, moduledefinition.ModuleDefinitionId, moduledefinition.Permissions);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (permissions.Where(item => item.EntityId == moduledefinition.ModuleDefinitionId).Any())
|
||||
{
|
||||
moduledefinition.Permissions = permissions.Where(item => item.EntityId == moduledefinition.ModuleDefinitionId).EncodePermissions();
|
||||
}
|
||||
else
|
||||
{
|
||||
_permissions.UpdatePermissions(siteId, EntityNames.ModuleDefinition, moduledefinition.ModuleDefinitionId, moduledefinition.Permissions);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// clean up any orphaned permissions
|
||||
var ids = new HashSet<int>(moduleDefinitions.Select(item => item.ModuleDefinitionId));
|
||||
foreach (var permission in permissions.Where(item => !ids.Contains(item.EntityId)))
|
||||
{
|
||||
_permissions.DeletePermission(permission.PermissionId);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
moduleDefinitions = LoadModuleDefinitions();
|
||||
}
|
||||
|
||||
return moduleDefinitions;
|
||||
}
|
||||
|
||||
private List<ModuleDefinition> LoadSiteModuleDefinitions(int siteId)
|
||||
private List<ModuleDefinition> LoadModuleDefinitions()
|
||||
{
|
||||
if (_moduleDefinitions == null)
|
||||
{
|
||||
// get module assemblies
|
||||
_moduleDefinitions = LoadModuleDefinitionsFromAssemblies();
|
||||
}
|
||||
|
||||
List<ModuleDefinition> moduleDefinitions = _moduleDefinitions;
|
||||
|
||||
List<Permission> permissions = new List<Permission>();
|
||||
if (siteId != -1)
|
||||
{
|
||||
// get module definition permissions for site
|
||||
permissions = _permissions.GetPermissions(siteId, EntityNames.ModuleDefinition).ToList();
|
||||
}
|
||||
// get module assemblies
|
||||
List<ModuleDefinition> moduleDefinitions = LoadModuleDefinitionsFromAssemblies();
|
||||
|
||||
// get module definitions in database
|
||||
List<ModuleDefinition> moduledefs = _db.ModuleDefinition.ToList();
|
||||
@ -95,13 +122,9 @@ namespace Oqtane.Repository
|
||||
if (moduledef == null)
|
||||
{
|
||||
// new module definition
|
||||
moduledef = new ModuleDefinition {ModuleDefinitionName = moduledefinition.ModuleDefinitionName};
|
||||
moduledef = new ModuleDefinition { ModuleDefinitionName = moduledefinition.ModuleDefinitionName };
|
||||
_db.ModuleDefinition.Add(moduledef);
|
||||
_db.SaveChanges();
|
||||
if (siteId != -1)
|
||||
{
|
||||
_permissions.UpdatePermissions(siteId, EntityNames.ModuleDefinition, moduledef.ModuleDefinitionId, moduledefinition.Permissions);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -126,31 +149,11 @@ namespace Oqtane.Repository
|
||||
moduledefinition.Version = moduledef.Version;
|
||||
}
|
||||
|
||||
if (siteId != -1)
|
||||
{
|
||||
if (permissions.Count == 0)
|
||||
{
|
||||
_permissions.UpdatePermissions(siteId, EntityNames.ModuleDefinition, moduledef.ModuleDefinitionId, moduledefinition.Permissions);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (permissions.Where(item => item.EntityId == moduledef.ModuleDefinitionId).Any())
|
||||
{
|
||||
moduledefinition.Permissions = permissions.Where(item => item.EntityId == moduledef.ModuleDefinitionId).EncodePermissions();
|
||||
}
|
||||
else
|
||||
{
|
||||
_permissions.UpdatePermissions(siteId, EntityNames.ModuleDefinition, moduledef.ModuleDefinitionId, moduledefinition.Permissions);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// remove module definition from list as it is already synced
|
||||
moduledefs.Remove(moduledef);
|
||||
}
|
||||
|
||||
moduledefinition.ModuleDefinitionId = moduledef.ModuleDefinitionId;
|
||||
moduledefinition.SiteId = siteId;
|
||||
moduledefinition.CreatedBy = moduledef.CreatedBy;
|
||||
moduledefinition.CreatedOn = moduledef.CreatedOn;
|
||||
moduledefinition.ModifiedBy = moduledef.ModifiedBy;
|
||||
@ -160,11 +163,6 @@ namespace Oqtane.Repository
|
||||
// any remaining module definitions are orphans
|
||||
foreach (ModuleDefinition moduledefinition in moduledefs)
|
||||
{
|
||||
if (siteId != -1)
|
||||
{
|
||||
_permissions.DeletePermissions(siteId, EntityNames.ModuleDefinition, moduledefinition.ModuleDefinitionId);
|
||||
}
|
||||
|
||||
_db.ModuleDefinition.Remove(moduledefinition); // delete
|
||||
_db.SaveChanges();
|
||||
}
|
||||
@ -175,11 +173,15 @@ namespace Oqtane.Repository
|
||||
private List<ModuleDefinition> LoadModuleDefinitionsFromAssemblies()
|
||||
{
|
||||
List<ModuleDefinition> moduleDefinitions = new List<ModuleDefinition>();
|
||||
|
||||
// iterate through Oqtane module assemblies
|
||||
var assemblies = AppDomain.CurrentDomain.GetOqtaneAssemblies();
|
||||
foreach (Assembly assembly in assemblies)
|
||||
{
|
||||
moduleDefinitions = LoadModuleDefinitionsFromAssembly(moduleDefinitions, assembly);
|
||||
if (System.IO.File.Exists(Path.Combine(Path.GetDirectoryName(Assembly.GetEntryAssembly().Location), Utilities.GetTypeName(assembly.FullName) + ".dll")))
|
||||
{
|
||||
moduleDefinitions = LoadModuleDefinitionsFromAssembly(moduleDefinitions, assembly);
|
||||
}
|
||||
}
|
||||
|
||||
return moduleDefinitions;
|
||||
|
@ -408,32 +408,6 @@ namespace Oqtane.Repository
|
||||
Content = ""
|
||||
}
|
||||
}
|
||||
}); pageTemplates.Add(new PageTemplate
|
||||
{
|
||||
Name = "Tenant Management",
|
||||
Parent = "Admin",
|
||||
Path = "admin/tenants",
|
||||
Icon = Icons.List,
|
||||
IsNavigation = false,
|
||||
IsPersonalizable = false,
|
||||
PagePermissions = new List<Permission>
|
||||
{
|
||||
new Permission(PermissionNames.View, RoleNames.Host, true),
|
||||
new Permission(PermissionNames.Edit, RoleNames.Host, true)
|
||||
}.EncodePermissions(),
|
||||
PageTemplateModules = new List<PageTemplateModule>
|
||||
{
|
||||
new PageTemplateModule
|
||||
{
|
||||
ModuleDefinitionName = typeof(Oqtane.Modules.Admin.Tenants.Index).ToModuleDefinitionName(), Title = "Tenant Management", Pane = "Content",
|
||||
ModulePermissions = new List<Permission>
|
||||
{
|
||||
new Permission(PermissionNames.View, RoleNames.Host, true),
|
||||
new Permission(PermissionNames.Edit, RoleNames.Host, true)
|
||||
}.EncodePermissions(),
|
||||
Content = ""
|
||||
}
|
||||
}
|
||||
});
|
||||
pageTemplates.Add(new PageTemplate
|
||||
{
|
||||
|
@ -1,7 +1,9 @@
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using Microsoft.Extensions.Caching.Memory;
|
||||
using Oqtane.Models;
|
||||
using Oqtane.Shared;
|
||||
using Oqtane.Themes;
|
||||
@ -10,7 +12,12 @@ namespace Oqtane.Repository
|
||||
{
|
||||
public class ThemeRepository : IThemeRepository
|
||||
{
|
||||
private List<Theme> _themes; // lazy load
|
||||
private readonly IMemoryCache _cache;
|
||||
|
||||
public ThemeRepository(IMemoryCache cache)
|
||||
{
|
||||
_cache = cache;
|
||||
}
|
||||
|
||||
public IEnumerable<Theme> GetThemes()
|
||||
{
|
||||
@ -19,12 +26,14 @@ namespace Oqtane.Repository
|
||||
|
||||
private List<Theme> LoadThemes()
|
||||
{
|
||||
if (_themes == null)
|
||||
// get module definitions
|
||||
List<Theme> themes = _cache.GetOrCreate("themes", entry =>
|
||||
{
|
||||
// get themes
|
||||
_themes = LoadThemesFromAssemblies();
|
||||
}
|
||||
return _themes;
|
||||
entry.SlidingExpiration = TimeSpan.FromMinutes(30);
|
||||
return LoadThemesFromAssemblies();
|
||||
});
|
||||
|
||||
return themes;
|
||||
}
|
||||
|
||||
private List<Theme> LoadThemesFromAssemblies()
|
||||
@ -35,7 +44,10 @@ namespace Oqtane.Repository
|
||||
var assemblies = AppDomain.CurrentDomain.GetOqtaneAssemblies();
|
||||
foreach (Assembly assembly in assemblies)
|
||||
{
|
||||
themes = LoadThemesFromAssembly(themes, assembly);
|
||||
if (System.IO.File.Exists(Path.Combine(Path.GetDirectoryName(Assembly.GetEntryAssembly().Location), Utilities.GetTypeName(assembly.FullName) + ".dll")))
|
||||
{
|
||||
themes = LoadThemesFromAssembly(themes, assembly);
|
||||
}
|
||||
}
|
||||
|
||||
return themes;
|
||||
@ -143,5 +155,10 @@ namespace Oqtane.Repository
|
||||
}
|
||||
return themes;
|
||||
}
|
||||
|
||||
public void DeleteTheme(string ThemeName)
|
||||
{
|
||||
_cache.Remove("themes");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
|
||||
Version 2.0.0 Tenant migration script
|
||||
Version 2.0.1 Tenant migration script
|
||||
|
||||
*/
|
||||
|
||||
|
17
Oqtane.Server/Scripts/Tenant.02.00.01.03.sql
Normal file
17
Oqtane.Server/Scripts/Tenant.02.00.01.03.sql
Normal file
@ -0,0 +1,17 @@
|
||||
/*
|
||||
|
||||
Version 2.0.1 Tenant migration script
|
||||
|
||||
*/
|
||||
|
||||
DELETE FROM [dbo].[Page]
|
||||
WHERE Path = 'admin/tenants';
|
||||
GO
|
||||
|
||||
ALTER TABLE [dbo].[Site] ADD
|
||||
[AdminContainerType] [nvarchar](200) NULL
|
||||
GO
|
||||
|
||||
UPDATE [dbo].[Site] SET AdminContainerType = ''
|
||||
GO
|
||||
|
@ -26,7 +26,6 @@ namespace Oqtane
|
||||
{
|
||||
public class Startup
|
||||
{
|
||||
private string _webRoot;
|
||||
private Runtime _runtime;
|
||||
private bool _useSwagger;
|
||||
private IWebHostEnvironment _env;
|
||||
@ -48,7 +47,6 @@ namespace Oqtane
|
||||
//add possibility to switch off swagger on production.
|
||||
_useSwagger = Configuration.GetSection("UseSwagger").Value != "false";
|
||||
|
||||
_webRoot = env.WebRootPath;
|
||||
AppDomain.CurrentDomain.SetData("DataDirectory", Path.Combine(env.ContentRootPath, "Data"));
|
||||
|
||||
_env = env;
|
||||
@ -181,7 +179,7 @@ namespace Oqtane
|
||||
services.AddSingleton<IDatabaseManager, DatabaseManager>();
|
||||
|
||||
// install any modules or themes ( this needs to occur BEFORE the assemblies are loaded into the app domain )
|
||||
InstallationManager.InstallPackages("Modules,Themes", _webRoot);
|
||||
InstallationManager.InstallPackages("Modules,Themes", _env.WebRootPath, _env.ContentRootPath);
|
||||
|
||||
// register transient scoped core services
|
||||
services.AddTransient<IModuleDefinitionRepository, ModuleDefinitionRepository>();
|
||||
|
Reference in New Issue
Block a user