diff --git a/Oqtane.Client/Modules/Admin/Themes/Index.razor b/Oqtane.Client/Modules/Admin/Themes/Index.razor
index 61076ca2..9f5a76e2 100644
--- a/Oqtane.Client/Modules/Admin/Themes/Index.razor
+++ b/Oqtane.Client/Modules/Admin/Themes/Index.razor
@@ -1,4 +1,5 @@
@namespace Oqtane.Modules.Admin.Themes
+@using System.Net
@inherits ModuleBase
@inject NavigationManager NavigationManager
@inject IThemeService ThemeService
@@ -14,25 +15,27 @@ else
+ |
@if (context.AssemblyName != "Oqtane.Client")
- {
+ {
- }
+ }
|
@context.Name |
@context.Version |
@if (UpgradeAvailable(context.ThemeName, context.Version))
- {
+ {
- }
+ }
|
diff --git a/Oqtane.Client/Modules/Admin/Themes/View.razor b/Oqtane.Client/Modules/Admin/Themes/View.razor
new file mode 100644
index 00000000..eb655799
--- /dev/null
+++ b/Oqtane.Client/Modules/Admin/Themes/View.razor
@@ -0,0 +1,101 @@
+@namespace Oqtane.Modules.Admin.Themes
+@using System.Net
+@inherits ModuleBase
+@inject IThemeService ThemeService
+@inject NavigationManager NavigationManager
+
+
+Cancel
+
+@code {
+ private string _themeName = "";
+ private string _name;
+ private string _version;
+ private string _owner = "";
+ private string _url = "";
+ private string _contact = "";
+ private string _license = "";
+
+ public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Host;
+
+ protected override async Task OnInitializedAsync()
+ {
+ try
+ {
+ _themeName = WebUtility.UrlDecode(PageState.QueryString["name"]);
+ var themes = await ThemeService.GetThemesAsync();
+ var theme = themes.FirstOrDefault(item => item.ThemeName == _themeName);
+ if (theme != null)
+ {
+ _name = theme.Name;
+ _version = theme.Version;
+ _owner = theme.Owner;
+ _url = theme.Url;
+ _contact = theme.Contact;
+ _license = theme.License;
+ }
+ }
+ catch (Exception ex)
+ {
+ await logger.LogError(ex, "Error Loading Theme {ThemeName} {Error}", _themeName, ex.Message);
+ AddModuleMessage("Error Loading Theme", MessageType.Error);
+ }
+ }
+}
diff --git a/Oqtane.Server/Repository/ModuleDefinitionRepository.cs b/Oqtane.Server/Repository/ModuleDefinitionRepository.cs
index 4a600a62..7521b9f3 100644
--- a/Oqtane.Server/Repository/ModuleDefinitionRepository.cs
+++ b/Oqtane.Server/Repository/ModuleDefinitionRepository.cs
@@ -188,6 +188,7 @@ namespace Oqtane.Repository
private List LoadModuleDefinitionsFromAssembly(List moduledefinitions, Assembly assembly)
{
ModuleDefinition moduledefinition;
+
Type[] modulecontroltypes = assembly.GetTypes().Where(item => item.GetInterfaces().Contains(typeof(IModuleControl))).ToArray();
foreach (Type modulecontroltype in modulecontroltypes)
{
@@ -198,8 +199,8 @@ namespace Oqtane.Repository
|| modulecontroltype.IsOqtaneIgnore()
) continue;
- string moduleNamespace = modulecontroltype.Namespace;
- string qualifiedModuleType = moduleNamespace + ", " + modulecontroltype.Assembly.GetName().Name;
+ // create namespace root typename
+ string qualifiedModuleType = modulecontroltype.Namespace + ", " + modulecontroltype.Assembly.GetName().Name;
int index = moduledefinitions.FindIndex(item => item.ModuleDefinitionName == qualifiedModuleType);
if (index == -1)
@@ -208,7 +209,7 @@ namespace Oqtane.Repository
Type moduletype = assembly
.GetTypes()
.Where(item => item.Namespace != null)
- .Where(item => item.Namespace.StartsWith(moduleNamespace))
+ .Where(item => item.Namespace == modulecontroltype.Namespace || item.Namespace.StartsWith(modulecontroltype.Namespace + "."))
.FirstOrDefault(item => item.GetInterfaces().Contains(typeof(IModule)));
if (moduletype != null)
{
@@ -221,8 +222,8 @@ namespace Oqtane.Repository
// set default property values
moduledefinition = new ModuleDefinition
{
- Name = moduleNamespace.Substring(moduleNamespace.LastIndexOf(".") + 1),
- Description = "Manage " + moduleNamespace.Substring(moduleNamespace.LastIndexOf(".") + 1),
+ Name = Utilities.GetTypeNameLastSegment(modulecontroltype.Namespace, 0),
+ Description = "Manage " + Utilities.GetTypeNameLastSegment(modulecontroltype.Namespace, 0),
Categories = ((qualifiedModuleType.StartsWith("Oqtane.Modules.Admin.")) ? "Admin" : "")
};
}
@@ -230,7 +231,7 @@ namespace Oqtane.Repository
// set internal properties
moduledefinition.ModuleDefinitionName = qualifiedModuleType;
moduledefinition.Version = ""; // will be populated from database
- moduledefinition.ControlTypeTemplate = moduleNamespace + "." + Constants.ActionToken + ", " + modulecontroltype.Assembly.GetName().Name;
+ moduledefinition.ControlTypeTemplate = modulecontroltype.Namespace + "." + Constants.ActionToken + ", " + modulecontroltype.Assembly.GetName().Name;
moduledefinition.AssemblyName = assembly.GetName().Name;
if (string.IsNullOrEmpty(moduledefinition.Categories))
diff --git a/Oqtane.Server/Repository/ThemeRepository.cs b/Oqtane.Server/Repository/ThemeRepository.cs
index 13fe85dc..bc14de74 100644
--- a/Oqtane.Server/Repository/ThemeRepository.cs
+++ b/Oqtane.Server/Repository/ThemeRepository.cs
@@ -44,36 +44,33 @@ namespace Oqtane.Repository
private List LoadThemesFromAssembly(List themes, Assembly assembly)
{
Theme theme;
+ List themeTypes = new List();
+
Type[] themeControlTypes = assembly.GetTypes().Where(item => item.GetInterfaces().Contains(typeof(IThemeControl))).ToArray();
foreach (Type themeControlType in themeControlTypes)
{
// Check if type should be ignored
if (themeControlType.Name == "ThemeBase"
|| themeControlType.IsGenericType
+ || themeControlType.IsAbstract
|| themeControlType.IsOqtaneIgnore()
) continue;
- string themeNamespace = themeControlType.Namespace;
- // 2dm disabled - not used anywhere in code
- //string qualifiedModuleType = themeNamespace + ", " + themeControlType.Assembly.GetName().Name;
-
- int index = themes.FindIndex(item => item.ThemeName == themeNamespace);
-
- // Find all types in the assembly which have the same namespace-root as the theme file
- // Check with "." in the end to
- List typesInTheme = assembly.GetTypes()
- .Where(item=>!item.IsOqtaneIgnore())
- .Where(item => item.Namespace != null)
- // Namespace must be the same or start with "xxx." to ensure that
- // similar namespaces like "MyTheme" and "MyTheme2" don't match in StartsWith(...)
- .Where(item => item.Namespace == themeNamespace
- || item.Namespace.StartsWith(themeNamespace + "."))
- .ToList();
+ // create namespace root typename
+ string qualifiedThemeType = themeControlType.Namespace + ", " + themeControlType.Assembly.GetName().Name;
+ int index = themes.FindIndex(item => item.ThemeName == qualifiedThemeType);
if (index == -1)
{
+ // Find all types in the assembly with the same namespace root
+ themeTypes = assembly.GetTypes()
+ .Where(item => !item.IsOqtaneIgnore())
+ .Where(item => item.Namespace != null)
+ .Where(item => item.Namespace == themeControlType.Namespace || item.Namespace.StartsWith(themeControlType.Namespace + "."))
+ .ToList();
+
// determine if this theme implements ITheme
- Type themetype = typesInTheme
+ Type themetype = themeTypes
.FirstOrDefault(item => item.GetInterfaces().Contains(typeof(ITheme)));
if (themetype != null)
{
@@ -89,19 +86,19 @@ namespace Oqtane.Repository
};
}
// set internal properties
- theme.ThemeName = themeNamespace;
+ theme.ThemeName = qualifiedThemeType;
theme.ThemeControls = "";
theme.PaneLayouts = "";
theme.ContainerControls = "";
theme.AssemblyName = assembly.FullName.Split(",")[0];
themes.Add(theme);
- index = themes.FindIndex(item => item.ThemeName == themeNamespace);
+ index = themes.FindIndex(item => item.ThemeName == qualifiedThemeType);
}
theme = themes[index];
theme.ThemeControls += (themeControlType.FullName + ", " + themeControlType.Assembly.GetName().Name + ";");
// layouts
- Type[] layouttypes = typesInTheme
+ Type[] layouttypes = themeTypes
.Where(item => item.GetInterfaces().Contains(typeof(ILayoutControl))).ToArray();
foreach (Type layouttype in layouttypes)
{
@@ -113,7 +110,7 @@ namespace Oqtane.Repository
}
// containers
- Type[] containertypes = typesInTheme
+ Type[] containertypes = themeTypes
.Where(item => item.GetInterfaces().Contains(typeof(IContainerControl))).ToArray();
foreach (Type containertype in containertypes)
{