diff --git a/Oqtane.Client/Modules/Admin/ModuleCreator/Index.razor b/Oqtane.Client/Modules/Admin/ModuleCreator/Index.razor index 0354f1bd..8d12407f 100644 --- a/Oqtane.Client/Modules/Admin/ModuleCreator/Index.razor +++ b/Oqtane.Client/Modules/Admin/ModuleCreator/Index.razor @@ -100,7 +100,7 @@ else public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Host; - protected override async Task OnInitializedAsync() + protected override async Task OnParametersSetAsync() { try { @@ -160,8 +160,7 @@ else Module module = await ModuleService.GetModuleAsync(ModuleState.ModuleId); module.ModuleDefinitionName = _moduledefinitionname; await ModuleService.UpdateModuleAsync(module); - ClearModuleMessage(); - NavigationManager.NavigateTo(NavigateUrl()); + NavigationManager.NavigateTo(NavigateUrl(), true); } } catch (Exception ex) diff --git a/Oqtane.Client/Modules/Admin/ModuleDefinitions/Create.razor b/Oqtane.Client/Modules/Admin/ModuleDefinitions/Create.razor new file mode 100644 index 00000000..dc14fd63 --- /dev/null +++ b/Oqtane.Client/Modules/Admin/ModuleDefinitions/Create.razor @@ -0,0 +1,158 @@ +@namespace Oqtane.Modules.Admin.ModuleDefinitions +@inherits ModuleBase +@inject NavigationManager NavigationManager +@inject IModuleDefinitionService ModuleDefinitionService +@inject IModuleService ModuleService +@inject ISystemService SystemService +@inject ISettingService SettingService +@inject IStringLocalizer Localizer +@using System.Text.RegularExpressions +@using System.IO; + +@if (_systeminfo != null && _templates != null) +{ + + + + + + + + + + + + + + + + + + + + + + @if (!string.IsNullOrEmpty(_location)) + { + + + + + } +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + @Localizer["Cancel"] +} + +@code { + private string _owner = string.Empty; + private string _module = string.Empty; + private string _description = string.Empty; + private string _template = "-"; + private string _reference = Constants.Version; + private string _location = string.Empty; + + private Dictionary _systeminfo; + private List _templates; + + public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Host; + + protected override async Task OnParametersSetAsync() + { + try + { + _systeminfo = await SystemService.GetSystemInfoAsync(); + _templates = await ModuleDefinitionService.GetModuleDefinitionTemplatesAsync(); + AddModuleMessage(Localizer["Please Note That The Module Creator Is Only Intended To Be Used In A Development Environment"], MessageType.Info); + } + catch (Exception ex) + { + await logger.LogError(ex, "Error Loading Module Creator"); + } + } + + private async Task CreateModule() + { + try + { + if (IsValid(_owner) && IsValid(_module) && _owner != _module && _template != "-") + { + var moduleDefinition = new ModuleDefinition { Owner = _owner, Name = _module, Description = _description, Template = _template, Version = _reference }; + moduleDefinition = await ModuleDefinitionService.CreateModuleDefinitionAsync(moduleDefinition); + GetLocation(); + AddModuleMessage(Localizer["The Source Code For Your Module Has Been Created At The Location Specified Below And Must Be Compiled In Order To Make It Functional. Once It Has Been Compiled You Must Restart Your Application To Activate The Module.", NavigateUrl("admin/system")], MessageType.Success); + } + else + { + AddModuleMessage(Localizer["You Must Provide A Valid Owner Name And Module Name ( ie. No Punctuation Or Spaces And The Values Cannot Be The Same ) And Choose A Template"], MessageType.Warning); + } + } + catch (Exception ex) + { + await logger.LogError(ex, "Error Creating Module"); + } + } + + private bool IsValid(string name) + { + // must contain letters, underscores and digits and first character must be letter or underscore + return !string.IsNullOrEmpty(name) && Regex.IsMatch(name, "^[A-Za-z_][A-Za-z0-9_]*$"); + } + + private void TemplateChanged(ChangeEventArgs e) + { + _template = (string)e.Value; + GetLocation(); + } + + private void GetLocation() + { + _location = string.Empty; + if (_template != "-" && _systeminfo != null && _systeminfo.ContainsKey("serverpath")) + { + string[] path = _systeminfo["serverpath"].Split(Path.DirectorySeparatorChar); + _location = string.Join(Path.DirectorySeparatorChar, path, 0, path.Length - 2) + + Path.DirectorySeparatorChar + _owner + "." + _module; + } + StateHasChanged(); + } +} diff --git a/Oqtane.Client/Modules/Admin/ModuleDefinitions/Index.razor b/Oqtane.Client/Modules/Admin/ModuleDefinitions/Index.razor index 3ebfed0b..1a86754a 100644 --- a/Oqtane.Client/Modules/Admin/ModuleDefinitions/Index.razor +++ b/Oqtane.Client/Modules/Admin/ModuleDefinitions/Index.razor @@ -12,6 +12,8 @@ else { + @((MarkupString)" ") +
@@ -25,17 +27,17 @@ else @if (context.AssemblyName != "Oqtane.Client") - { + { - } + } @context.Name @context.Version @if (UpgradeAvailable(context.ModuleDefinitionName, context.Version)) - { + { - } + } diff --git a/Oqtane.Client/Modules/Admin/Modules/Settings.razor b/Oqtane.Client/Modules/Admin/Modules/Settings.razor index c6ebe5c3..f6e44eeb 100644 --- a/Oqtane.Client/Modules/Admin/Modules/Settings.razor +++ b/Oqtane.Client/Modules/Admin/Modules/Settings.razor @@ -8,7 +8,7 @@ @inject IStringLocalizer Localizer - + @if (_containers != null) { @@ -26,7 +26,6 @@
- +
}
- @if (_settingsModuleType != null) + @if (_moduleSettingsType != null) { - - @DynamicComponent + + @ModuleSettingsComponent + + } + @if (_containerSettingsType != null) + { + + @ContainerSettingsComponent }
@@ -87,6 +92,10 @@ @Localizer["Cancel"] @code { + public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Edit; + public override string Title => "Module Settings"; + + private List _themes; private List _containers = new List(); private string _title; private string _containerType; @@ -95,50 +104,65 @@ private string _permissions = null; private string _pageId; private PermissionGrid _permissionGrid; - private Type _settingsModuleType; - private string _settingstitle = "Other Settings"; - private object _settings; - - public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Edit; - public override string Title => "Module Settings"; - - private RenderFragment DynamicComponent { get; set; } + private Type _moduleSettingsType; + private object _moduleSettings; + private string _moduleSettingsTitle = "Module Settings"; + private RenderFragment ModuleSettingsComponent { get; set; } + private Type _containerSettingsType; + private object _containerSettings; + private RenderFragment ContainerSettingsComponent { get; set; } protected override async Task OnInitializedAsync() { _title = ModuleState.Title; - _containers = ThemeService.GetContainerControls(await ThemeService.GetThemesAsync(), PageState.Page.ThemeType); + _themes = await ThemeService.GetThemesAsync(); + _containers = ThemeService.GetContainerControls(_themes, PageState.Page.ThemeType); _containerType = ModuleState.ContainerType; - if (!string.IsNullOrEmpty(PageState.Page.DefaultContainerType) && _containerType == PageState.Page.DefaultContainerType) - { - _containerType = "-"; - } - if (_containerType == PageState.Site.DefaultContainerType) - { - _containerType = "-"; - } _allPages = ModuleState.AllPages.ToString(); _permissions = ModuleState.Permissions; _permissionNames = ModuleState.ModuleDefinition.PermissionNames; _pageId = ModuleState.PageId.ToString(); - _settingsModuleType = Type.GetType(ModuleState.ModuleDefinition.ControlTypeTemplate.Replace(Constants.ActionToken, PageState.Action), false, true); - if (_settingsModuleType != null) + if (!string.IsNullOrEmpty(ModuleState.ModuleDefinition.SettingsType)) { - var moduleobject = Activator.CreateInstance(_settingsModuleType) as IModuleControl; - _settingstitle = moduleobject.Title; - if (string.IsNullOrEmpty(_settingstitle)) + // module settings type explicitly declared in IModule interface + _moduleSettingsType = Type.GetType(ModuleState.ModuleDefinition.SettingsType); + } + else + { + // legacy support - module settings type determined by convention ( ie. existence of a "Settings.razor" component in module ) + _moduleSettingsType = Type.GetType(ModuleState.ModuleDefinition.ControlTypeTemplate.Replace(Constants.ActionToken, PageState.Action), false, true); + } + if (_moduleSettingsType != null) + { + var moduleobject = Activator.CreateInstance(_moduleSettingsType) as IModuleControl; + if (!string.IsNullOrEmpty(moduleobject.Title)) { - _settingstitle = "Other Settings"; + _moduleSettingsTitle = moduleobject.Title; } - DynamicComponent = builder => + ModuleSettingsComponent = builder => { - builder.OpenComponent(0, _settingsModuleType); - builder.AddComponentReferenceCapture(1, inst => { _settings = Convert.ChangeType(inst, _settingsModuleType); }); + builder.OpenComponent(0, _moduleSettingsType); + builder.AddComponentReferenceCapture(1, inst => { _moduleSettings = Convert.ChangeType(inst, _moduleSettingsType); }); builder.CloseComponent(); }; - } + } + + var theme = _themes.FirstOrDefault(item => item.Containers.Any(themecontrol => themecontrol.TypeName.Equals(_containerType))); + if (theme != null && !string.IsNullOrEmpty(theme.ContainerSettingsType)) + { + _containerSettingsType = Type.GetType(theme.ContainerSettingsType); + if (_containerSettingsType != null) + { + ContainerSettingsComponent = builder => + { + builder.OpenComponent(0, _containerSettingsType); + builder.AddComponentReferenceCapture(1, inst => { _containerSettings = Convert.ChangeType(inst, _containerSettingsType); }); + builder.CloseComponent(); + }; + } + } } private async Task SaveModule() @@ -163,16 +187,25 @@ module.Permissions = _permissionGrid.GetPermissions(); await ModuleService.UpdateModuleAsync(module); - - if (_settings is ISettingsControl control) + if (_moduleSettingsType != null) { - await control.UpdateSettings(); + if (_moduleSettings is ISettingsControl moduleSettingsControl) + { + // module settings updated using explicit interface + await moduleSettingsControl.UpdateSettings(); + } + else + { + // legacy support - module settings updated by convention ( ie. by calling a public method named "UpdateSettings" in settings component ) + _moduleSettings?.GetType().GetMethod("UpdateSettings")?.Invoke(_moduleSettings, null); + } } - else + + if (_containerSettingsType != null && _containerSettings is ISettingsControl containerSettingsControl) { - // Compatibility 2.0 fallback - _settings?.GetType().GetMethod("UpdateSettings")?.Invoke(_settings, null); // method must be public in settings component + await containerSettingsControl.UpdateSettings(); } + NavigationManager.NavigateTo(NavigateUrl()); } diff --git a/Oqtane.Client/Modules/Admin/Pages/Add.razor b/Oqtane.Client/Modules/Admin/Pages/Add.razor index b0234619..c2f44bee 100644 --- a/Oqtane.Client/Modules/Admin/Pages/Add.razor +++ b/Oqtane.Client/Modules/Admin/Pages/Add.razor @@ -102,7 +102,6 @@ - @if (_layouts.Count > 0) - { - - - - - - - - - } - @foreach (var theme in _themes) { @@ -117,37 +117,13 @@ - @if (_layouts.Count > 0) - { - - - - - - - - - } - @if (_layouts.Count > 0) - { - - - - - - - - - } @@ -244,7 +227,6 @@ private bool _initialized = false; private List _themeList; private List _themes = new List(); - private List _layouts = new List(); private List _containers = new List(); private string _name = string.Empty; private List _tenantList; @@ -256,7 +238,6 @@ private int _faviconfileid = -1; private FileManager _faviconfilemanager; private string _themetype = "-"; - private string _layouttype = "-"; private string _containertype = "-"; private string _admincontainertype = "-"; private string _allowregistration; @@ -309,8 +290,6 @@ _themes = ThemeService.GetThemeControls(_themeList); _themetype = site.DefaultThemeType; - _layouts = ThemeService.GetLayoutControls(_themeList, _themetype); - _layouttype = site.DefaultLayoutType; _containers = ThemeService.GetContainerControls(_themeList, _themetype); _containertype = site.DefaultContainerType; _admincontainertype = site.AdminContainerType; @@ -371,15 +350,12 @@ _themetype = (string)e.Value; if (_themetype != "-") { - _layouts = ThemeService.GetLayoutControls(_themeList, _themetype); _containers = ThemeService.GetContainerControls(_themeList, _themetype); } else { - _layouts = new List(); _containers = new List(); } - _layouttype = "-"; _containertype = "-"; _admincontainertype = ""; StateHasChanged(); @@ -395,7 +371,7 @@ { try { - if (_name != string.Empty && _urls != string.Empty && _themetype != "-" && (_layouts.Count == 0 || _layouttype != "-") && _containertype != "-") + if (_name != string.Empty && _urls != string.Empty && _themetype != "-" && _containertype != "-") { var unique = true; foreach (string name in _urls.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries)) @@ -427,7 +403,6 @@ } site.DefaultThemeType = _themetype; - site.DefaultLayoutType = (_layouttype == "-" ? string.Empty : _layouttype); site.DefaultContainerType = _containertype; site.AdminContainerType = _admincontainertype; site.AllowRegistration = (_allowregistration == null ? true : Boolean.Parse(_allowregistration)); @@ -491,7 +466,7 @@ } else { - AddModuleMessage(Localizer["You Must Provide A Site Name, Alias, And Default Theme/Layout/Container"], MessageType.Warning); + AddModuleMessage(Localizer["You Must Provide A Site Name, Alias, And Default Theme/Container"], MessageType.Warning); } } catch (Exception ex) diff --git a/Oqtane.Client/Modules/Admin/Sites/Add.razor b/Oqtane.Client/Modules/Admin/Sites/Add.razor index a4b430e9..5e3ac770 100644 --- a/Oqtane.Client/Modules/Admin/Sites/Add.razor +++ b/Oqtane.Client/Modules/Admin/Sites/Add.razor @@ -47,23 +47,6 @@ else - @if (_layouts.Count > 0) - { - - - - - - - - - } @@ -219,7 +202,6 @@ else @code { private List _themeList; private List _themes = new List(); - private List _layouts = new List(); private List _containers = new List(); private List _siteTemplates; private List _tenants; @@ -238,7 +220,6 @@ else private string _name = string.Empty; private string _urls = string.Empty; private string _themetype = "-"; - private string _layouttype = "-"; private string _containertype = "-"; private string _admincontainertype = ""; private string _sitetemplatetype = "-"; @@ -284,29 +265,26 @@ else _themetype = (string)e.Value; if (_themetype != "-") { - _layouts = ThemeService.GetLayoutControls(_themeList, _themetype); _containers = ThemeService.GetContainerControls(_themeList, _themetype); } else { - _layouts = new List(); _containers = new List(); } - _layouttype = "-"; _containertype = "-"; _admincontainertype = ""; StateHasChanged(); } catch (Exception ex) { - await logger.LogError(ex, "Error Loading Pane Layouts For Theme {ThemeType} {Error}", _themetype, ex.Message); - AddModuleMessage(Localizer["Error Loading Pane Layouts For Theme"], MessageType.Error); + await logger.LogError(ex, "Error Loading Containers For Theme {ThemeType} {Error}", _themetype, ex.Message); + AddModuleMessage(Localizer["Error Loading Containers For Theme"], MessageType.Error); } } private async Task SaveSite() { - if (_tenantid != "-" && _name != string.Empty && _urls != string.Empty && _themetype != "-" && (_layouts.Count == 0 || _layouttype != "-") && _containertype != "-" && _sitetemplatetype != "-") + if (_tenantid != "-" && _name != string.Empty && _urls != string.Empty && _themetype != "-" && _containertype != "-" && _sitetemplatetype != "-") { var duplicates = new List(); var aliases = await AliasService.GetAliasesAsync(); @@ -393,7 +371,6 @@ else config.SiteName = _name; config.Aliases = _urls.Replace("\n", ","); config.DefaultTheme = _themetype; - config.DefaultLayout = _layouttype; config.DefaultContainer = _containertype; config.DefaultAdminContainer = _admincontainertype; config.SiteTemplate = _sitetemplatetype; @@ -421,7 +398,7 @@ else } else { - AddModuleMessage(Localizer["You Must Provide A Tenant, Site Name, Alias, Default Theme/Layout/Container, And Site Template"], MessageType.Warning); + AddModuleMessage(Localizer["You Must Provide A Tenant, Site Name, Alias, Default Theme/Container, And Site Template"], MessageType.Warning); } } } diff --git a/Oqtane.Client/Modules/Admin/Sites/Edit.razor b/Oqtane.Client/Modules/Admin/Sites/Edit.razor index 6d28aee6..ca589019 100644 --- a/Oqtane.Client/Modules/Admin/Sites/Edit.razor +++ b/Oqtane.Client/Modules/Admin/Sites/Edit.razor @@ -40,23 +40,6 @@ - @if (_layouts.Count > 0) - { - - - - - - - - - } @@ -127,14 +110,12 @@ private bool _initialized = false; private List _themeList; private List _themes = new List(); - private List _layouts = new List(); private List _containers = new List(); private Alias _alias; private string _name = string.Empty; private List _aliasList; private string _urls = string.Empty; private string _themetype; - private string _layouttype; private string _containertype = "-"; private string _admincontainertype = "-"; private string _createdby; @@ -170,8 +151,6 @@ _themes = ThemeService.GetThemeControls(_themeList); _themetype = site.DefaultThemeType; - _layouts = ThemeService.GetLayoutControls(_themeList, _themetype); - _layouttype = site.DefaultLayoutType; _containers = ThemeService.GetContainerControls(_themeList, _themetype); _containertype = site.DefaultContainerType; _admincontainertype = site.AdminContainerType; @@ -208,15 +187,12 @@ _themetype = (string)e.Value; if (_themetype != "-") { - _layouts = ThemeService.GetLayoutControls(_themeList, _themetype); _containers = ThemeService.GetContainerControls(_themeList, _themetype); } else { - _layouts = new List(); _containers = new List(); } - _layouttype = "-"; _containertype = "-"; _admincontainertype = ""; StateHasChanged(); @@ -232,7 +208,7 @@ { try { - if (_name != string.Empty && _urls != string.Empty && _themetype != "-" && (_layouts.Count == 0 || _layouttype != "-") && _containertype != "-") + if (_name != string.Empty && _urls != string.Empty && _themetype != "-" && _containertype != "-") { var unique = true; foreach (string name in _urls.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries)) @@ -252,7 +228,6 @@ site.Name = _name; site.LogoFileId = null; site.DefaultThemeType = _themetype; - site.DefaultLayoutType = _layouttype ?? string.Empty; site.DefaultContainerType = _containertype; site.AdminContainerType = _admincontainertype; site.IsDeleted = (_isdeleted == null || Boolean.Parse(_isdeleted)); diff --git a/Oqtane.Client/Modules/Admin/ThemeCreator/ModuleInfo.cs b/Oqtane.Client/Modules/Admin/ThemeCreator/ModuleInfo.cs deleted file mode 100644 index 621b0953..00000000 --- a/Oqtane.Client/Modules/Admin/ThemeCreator/ModuleInfo.cs +++ /dev/null @@ -1,15 +0,0 @@ -using Oqtane.Models; - -namespace Oqtane.Modules.Admin.ThemeCreator -{ - public class ModuleInfo : IModule - { - public ModuleDefinition ModuleDefinition => new ModuleDefinition - { - Name = "Theme Creator", - Description = "Enables software developers to quickly create themes by automating many of the initial theme creation tasks", - Version = "1.0.0", - Categories = "Developer" - }; - } -} diff --git a/Oqtane.Client/Modules/Admin/ThemeCreator/Index.razor b/Oqtane.Client/Modules/Admin/Themes/Create.razor similarity index 76% rename from Oqtane.Client/Modules/Admin/ThemeCreator/Index.razor rename to Oqtane.Client/Modules/Admin/Themes/Create.razor index cc15b1da..c0e56188 100644 --- a/Oqtane.Client/Modules/Admin/ThemeCreator/Index.razor +++ b/Oqtane.Client/Modules/Admin/Themes/Create.razor @@ -1,8 +1,8 @@ -@namespace Oqtane.Modules.Admin.ThemeCreator +@namespace Oqtane.Modules.Admin.Themes @inherits ModuleBase @inject NavigationManager NavigationManager @inject IThemeService ThemeService -@inject IModuleService ModuleService +@inject IModuleService ModuleService @inject IPageModuleService PageModuleService @inject ISystemService SystemService @inject ISettingService SettingService @@ -10,7 +10,7 @@ @using System.Text.RegularExpressions @using System.IO; -@if (string.IsNullOrEmpty(_themename) && _systeminfo != null && _templates != null) +@if (_systeminfo != null && _templates != null) { @@ -73,14 +73,10 @@ }
-} -else -{ - + @Localizer["Cancel"] } @code { - private string _themename = string.Empty; private string _owner = string.Empty; private string _theme = string.Empty; private string _template = "-"; @@ -92,22 +88,13 @@ else public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Host; - protected override async Task OnInitializedAsync() + protected override async Task OnParametersSetAsync() { try { - _themename = SettingService.GetSetting(ModuleState.Settings, "ThemeName", ""); _systeminfo = await SystemService.GetSystemInfoAsync(); _templates = await ThemeService.GetThemeTemplatesAsync(); - - if (string.IsNullOrEmpty(_themename)) - { - AddModuleMessage(Localizer["Please Note That The Theme Creator Is Only Intended To Be Used In A Development Environment"], MessageType.Info); - } - else - { - AddModuleMessage(Localizer["Once You Have Compiled The Theme And Restarted The Application You Can Activate The Theme Below"], MessageType.Info); - } + AddModuleMessage(Localizer["Please Note That The Theme Creator Is Only Intended To Be Used In A Development Environment"], MessageType.Info); } catch (Exception ex) { @@ -123,14 +110,9 @@ else { var theme = new Theme { Owner = _owner, Name = _theme, Template = _template, Version = _reference }; theme = await ThemeService.CreateThemeAsync(theme); - - var settings = ModuleState.Settings; - SettingService.SetSetting(settings, "ThemeName", theme.ThemeName); - await SettingService.UpdateModuleSettingsAsync(settings, ModuleState.ModuleId); - GetLocation(); - AddModuleMessage(Localizer["The Source Code For Your Theme Has Been Created At The Location Specified Below And Must Be Compiled In Order To Make It Functional. Once It Has Been Compiled You Must Restart Your Application To Apply These Changes.", NavigateUrl("admin/system")], MessageType.Success); + AddModuleMessage(Localizer["The Source Code For Your Theme Has Been Created At The Location Specified Below And Must Be Compiled In Order To Make It Functional. Once It Has Been Compiled You Must Restart Your Application To Activate The Module.", NavigateUrl("admin/system")], MessageType.Success); } else { @@ -143,23 +125,6 @@ else } } - private async Task ActivateTheme() - { - try - { - if (!string.IsNullOrEmpty(_themename)) - { - await PageModuleService.DeletePageModuleAsync(ModuleState.PageModuleId); - await ModuleService.DeleteModuleAsync(ModuleState.ModuleId); - NavigationManager.NavigateTo(NavigateUrl()); - } - } - catch (Exception ex) - { - await logger.LogError(ex, "Error Activating Theme"); - } - } - private bool IsValid(string name) { // must contain letters, underscores and digits and first character must be letter or underscore diff --git a/Oqtane.Client/Modules/Admin/Themes/Index.razor b/Oqtane.Client/Modules/Admin/Themes/Index.razor index 9e8677f7..d87bbd8a 100644 --- a/Oqtane.Client/Modules/Admin/Themes/Index.razor +++ b/Oqtane.Client/Modules/Admin/Themes/Index.razor @@ -13,6 +13,8 @@ else { + @((MarkupString)" ") +
@@ -26,17 +28,17 @@ else @if (context.AssemblyName != "Oqtane.Client") - { + { - } + } @context.Name @context.Version @if (UpgradeAvailable(context.ThemeName, context.Version)) - { + { - } + } diff --git a/Oqtane.Client/Modules/Controls/RichTextEditor.razor b/Oqtane.Client/Modules/Controls/RichTextEditor.razor index 3a33cc33..1d3a2751 100644 --- a/Oqtane.Client/Modules/Controls/RichTextEditor.razor +++ b/Oqtane.Client/Modules/Controls/RichTextEditor.razor @@ -6,21 +6,24 @@
- @if (_filemanagervisible) + @if (AllowFileManagement) { - - -
- } -
-    - @if (_filemanagervisible) { - @((MarkupString)"  ") - + + +
} -
+
+    + + @if (_filemanagervisible) + { + @((MarkupString)"  ") + + } +
+ }
@@ -107,6 +110,9 @@ [Parameter] public string DebugLevel { get; set; } = "info"; + [Parameter] + public bool AllowFileManagement { get; set; } = true; + public override List Resources => new List() { new Resource { ResourceType = ResourceType.Script, Bundle = "Quill", Url = "js/quill1.3.6.min.js" }, diff --git a/Oqtane.Client/Modules/Controls/TabPanel.razor b/Oqtane.Client/Modules/Controls/TabPanel.razor index e618c896..d6be85f6 100644 --- a/Oqtane.Client/Modules/Controls/TabPanel.razor +++ b/Oqtane.Client/Modules/Controls/TabPanel.razor @@ -30,16 +30,12 @@ else [Parameter] public SecurityAccessLevel? Security { get; set; } // optional - can be used to specify SecurityAccessLevel - protected override void OnInitialized() - { - base.OnInitialized(); - Parent.AddTabPanel((TabPanel)this); - } - protected override void OnParametersSet() { base.OnParametersSet(); + Parent.AddTabPanel((TabPanel)this); + if (string.IsNullOrEmpty(Heading)) { Name = Localize(nameof(Name), Name); diff --git a/Oqtane.Client/Modules/Controls/TabStrip.razor b/Oqtane.Client/Modules/Controls/TabStrip.razor index d5186930..41153b57 100644 --- a/Oqtane.Client/Modules/Controls/TabStrip.razor +++ b/Oqtane.Client/Modules/Controls/TabStrip.razor @@ -9,7 +9,7 @@ { @if (IsAuthorized(tabPanel)) { -
  • +
  • @if (tabPanel.Name == ActiveTab) { @@ -35,7 +35,7 @@ @code { - private List _tabPanels = new List(); + private List _tabPanels; [Parameter] public RenderFragment ChildContent { get; set; } // contains the TabPanels @@ -51,14 +51,22 @@ } } + protected override void OnParametersSet() + { + _tabPanels = new List(); + } + internal void AddTabPanel(TabPanel tabPanel) { - _tabPanels.Add(tabPanel); - if (string.IsNullOrEmpty(ActiveTab)) + if (!_tabPanels.Exists(item => item.Name == tabPanel.Name)) { - ActiveTab = tabPanel.Name; + _tabPanels.Add(tabPanel); + if (string.IsNullOrEmpty(ActiveTab)) + { + ActiveTab = tabPanel.Name; + } + StateHasChanged(); } - StateHasChanged(); } private bool IsAuthorized(TabPanel tabPanel) diff --git a/Oqtane.Client/Modules/HtmlText/Edit.razor b/Oqtane.Client/Modules/HtmlText/Edit.razor index 311c4cd7..ee60134e 100644 --- a/Oqtane.Client/Modules/HtmlText/Edit.razor +++ b/Oqtane.Client/Modules/HtmlText/Edit.razor @@ -4,12 +4,13 @@ @namespace Oqtane.Modules.HtmlText @inherits ModuleBase @inject IHtmlTextService HtmlTextService +@inject ISettingService SettingService @inject NavigationManager NavigationManager @inject IStringLocalizer Localizer @if (_content != null) { - + @Localizer["Cancel"] @if (!string.IsNullOrEmpty(_content)) @@ -26,13 +27,14 @@ public override string Title => "Edit Html/Text"; public override List Resources => new List() - { +{ new Resource { ResourceType = ResourceType.Stylesheet, Url = ModulePath() + "Module.css" }, new Resource { ResourceType = ResourceType.Stylesheet, Url = "css/quill/quill1.3.6.bubble.css" }, new Resource { ResourceType = ResourceType.Stylesheet, Url = "css/quill/quill1.3.6.snow.css" } }; private RichTextEditor RichTextEditorHtml; + private bool _allowfilemanagement; private string _content = null; private string _createdby; private DateTime _createdon; @@ -43,6 +45,8 @@ { try { + _allowfilemanagement = bool.Parse(SettingService.GetSetting(ModuleState.Settings, "AllowFileManagement", "true")); + var htmltext = await HtmlTextService.GetHtmlTextAsync(ModuleState.ModuleId); if (htmltext != null) { diff --git a/Oqtane.Client/Modules/HtmlText/ModuleInfo.cs b/Oqtane.Client/Modules/HtmlText/ModuleInfo.cs index 4be90a8b..5e998f96 100644 --- a/Oqtane.Client/Modules/HtmlText/ModuleInfo.cs +++ b/Oqtane.Client/Modules/HtmlText/ModuleInfo.cs @@ -1,4 +1,4 @@ -using Oqtane.Models; +using Oqtane.Models; namespace Oqtane.Modules.HtmlText { @@ -10,7 +10,8 @@ namespace Oqtane.Modules.HtmlText Description = "Renders HTML or Text Content", Version = "1.0.0", ServerManagerType = "Oqtane.Modules.HtmlText.Manager.HtmlTextManager, Oqtane.Server", - ReleaseVersions = "1.0.0" + ReleaseVersions = "1.0.0", + SettingsType = "Oqtane.Modules.HtmlText.Settings, Oqtane.Client" }; } } diff --git a/Oqtane.Client/Modules/HtmlText/Settings.razor b/Oqtane.Client/Modules/HtmlText/Settings.razor new file mode 100644 index 00000000..6e7795e4 --- /dev/null +++ b/Oqtane.Client/Modules/HtmlText/Settings.razor @@ -0,0 +1,49 @@ +@namespace Oqtane.Modules.HtmlText +@inherits ModuleBase +@inject ISettingService SettingService +@implements Oqtane.Interfaces.ISettingsControl +@inject IStringLocalizer Localizer + + + + + + +
    + + + +
    + +@code { + private string _allowfilemanagement; + + protected override void OnInitialized() + { + try + { + _allowfilemanagement = SettingService.GetSetting(ModuleState.Settings, "AllowFileManagement", "true"); + } + catch (Exception ex) + { + ModuleInstance.AddModuleMessage(ex.Message, MessageType.Error); + } + } + + public async Task UpdateSettings() + { + try + { + var settings = ModuleState.Settings; + settings = SettingService.SetSetting(settings, "AllowFileManagement", _allowfilemanagement); + await SettingService.UpdateModuleSettingsAsync(settings, ModuleState.ModuleId); + } + catch (Exception ex) + { + ModuleInstance.AddModuleMessage(ex.Message, MessageType.Error); + } + } +} diff --git a/Oqtane.Client/Program.cs b/Oqtane.Client/Program.cs index 558b8290..ca60b063 100644 --- a/Oqtane.Client/Program.cs +++ b/Oqtane.Client/Program.cs @@ -129,19 +129,19 @@ namespace Oqtane.Client foreach (ZipArchiveEntry entry in archive.Entries) { - if (!assemblies.Contains(Path.GetFileNameWithoutExtension(entry.Name))) + if (!assemblies.Contains(Path.GetFileNameWithoutExtension(entry.FullName))) { using (var memoryStream = new MemoryStream()) { entry.Open().CopyTo(memoryStream); byte[] file = memoryStream.ToArray(); - switch (Path.GetExtension(entry.Name)) + switch (Path.GetExtension(entry.FullName)) { case ".dll": - dlls.Add(entry.Name, file); + dlls.Add(entry.FullName, file); break; case ".pdb": - pdbs.Add(entry.Name, file); + pdbs.Add(entry.FullName, file); break; } } diff --git a/Oqtane.Client/Services/ThemeService.cs b/Oqtane.Client/Services/ThemeService.cs index c58c7178..ac79ad88 100644 --- a/Oqtane.Client/Services/ThemeService.cs +++ b/Oqtane.Client/Services/ThemeService.cs @@ -29,10 +29,10 @@ namespace Oqtane.Services return themes.SelectMany(item => item.Themes).ToList(); } + //[Obsolete("This method is deprecated.", false)] public List GetLayoutControls(List themes, string themeName) { - return themes.Where(item => Utilities.GetTypeName(themeName).StartsWith(Utilities.GetTypeName(item.ThemeName))) - .SelectMany(item => item.Layouts).ToList(); + return null; } public List GetContainerControls(List themes, string themeName) diff --git a/Oqtane.Client/Themes/BlazorTheme/Themes/Default.razor b/Oqtane.Client/Themes/BlazorTheme/Themes/Default.razor index dc723002..74444f48 100644 --- a/Oqtane.Client/Themes/BlazorTheme/Themes/Default.razor +++ b/Oqtane.Client/Themes/BlazorTheme/Themes/Default.razor @@ -17,13 +17,13 @@
  • - +
    @code { - public override string Panes => "Content"; + public override string Panes => PaneNames.Admin; public override List Resources => new List() { diff --git a/Oqtane.Client/Themes/Controls/ModuleActions.razor b/Oqtane.Client/Themes/Controls/Container/ModuleActions.razor similarity index 57% rename from Oqtane.Client/Themes/Controls/ModuleActions.razor rename to Oqtane.Client/Themes/Controls/Container/ModuleActions.razor index 2468bf89..7311d7e8 100644 --- a/Oqtane.Client/Themes/Controls/ModuleActions.razor +++ b/Oqtane.Client/Themes/Controls/Container/ModuleActions.razor @@ -22,21 +22,24 @@ } } -
  • - -  Move To > - -
      - @foreach (var action in Actions.Where(item => item.Name.Contains("Pane"))) - { -
    • - -  @action.Name - -
    • - } -
    -
  • + @if (Actions.Where(item => item.Name.Contains("Pane")).Any()) + { +
  • + +  Move To > + +
      + @foreach (var action in Actions.Where(item => item.Name.Contains("Pane"))) + { +
    • + +  @action.Name + +
    • + } +
    +
  • + }
    } diff --git a/Oqtane.Client/Themes/Controls/ModuleActionsBase.cs b/Oqtane.Client/Themes/Controls/Container/ModuleActionsBase.cs similarity index 100% rename from Oqtane.Client/Themes/Controls/ModuleActionsBase.cs rename to Oqtane.Client/Themes/Controls/Container/ModuleActionsBase.cs diff --git a/Oqtane.Client/Themes/Controls/ModuleTitle.razor b/Oqtane.Client/Themes/Controls/Container/ModuleTitle.razor similarity index 100% rename from Oqtane.Client/Themes/Controls/ModuleTitle.razor rename to Oqtane.Client/Themes/Controls/Container/ModuleTitle.razor diff --git a/Oqtane.Client/Themes/Controls/FontIcon.razor b/Oqtane.Client/Themes/Controls/FontIcon.razor deleted file mode 100644 index 04aad17e..00000000 --- a/Oqtane.Client/Themes/Controls/FontIcon.razor +++ /dev/null @@ -1,12 +0,0 @@ -@namespace Oqtane.Themes.Controls -@inherits ThemeControlBase - -@if (!string.IsNullOrWhiteSpace(Value)) -{ - -} - -@code { - [Parameter()] - public string Value { get; set; } -} \ No newline at end of file diff --git a/Oqtane.Client/Themes/Controls/Breadcrumbs.razor b/Oqtane.Client/Themes/Controls/Theme/Breadcrumbs.razor similarity index 100% rename from Oqtane.Client/Themes/Controls/Breadcrumbs.razor rename to Oqtane.Client/Themes/Controls/Theme/Breadcrumbs.razor diff --git a/Oqtane.Client/Themes/Controls/ControlPanel.razor b/Oqtane.Client/Themes/Controls/Theme/ControlPanel.razor similarity index 99% rename from Oqtane.Client/Themes/Controls/ControlPanel.razor rename to Oqtane.Client/Themes/Controls/Theme/ControlPanel.razor index c4d86cec..5c93bc9c 100644 --- a/Oqtane.Client/Themes/Controls/ControlPanel.razor +++ b/Oqtane.Client/Themes/Controls/Theme/ControlPanel.razor @@ -599,7 +599,7 @@ Dictionary settings = await SettingService.GetUserSettingsAsync(PageState.User.UserId); _category = SettingService.GetSetting(settings, settingCategory, "Common"); var pane = SettingService.GetSetting(settings, settingPane, ""); - _pane = PageState.Page.Panes.Contains(pane) ? pane : PageState.Page.Panes.FirstOrDefault(); + _pane = PageState.Page.Panes.Contains(pane) ? pane : PaneNames.Admin; } private async Task UpdateSettingsAsync() diff --git a/Oqtane.Client/Themes/Controls/LanguageSwitcher.razor b/Oqtane.Client/Themes/Controls/Theme/LanguageSwitcher.razor similarity index 100% rename from Oqtane.Client/Themes/Controls/LanguageSwitcher.razor rename to Oqtane.Client/Themes/Controls/Theme/LanguageSwitcher.razor diff --git a/Oqtane.Client/Themes/Controls/Login.razor b/Oqtane.Client/Themes/Controls/Theme/Login.razor similarity index 100% rename from Oqtane.Client/Themes/Controls/Login.razor rename to Oqtane.Client/Themes/Controls/Theme/Login.razor diff --git a/Oqtane.Client/Themes/Controls/LoginBase.cs b/Oqtane.Client/Themes/Controls/Theme/LoginBase.cs similarity index 100% rename from Oqtane.Client/Themes/Controls/LoginBase.cs rename to Oqtane.Client/Themes/Controls/Theme/LoginBase.cs diff --git a/Oqtane.Client/Themes/Controls/Logo.razor b/Oqtane.Client/Themes/Controls/Theme/Logo.razor similarity index 100% rename from Oqtane.Client/Themes/Controls/Logo.razor rename to Oqtane.Client/Themes/Controls/Theme/Logo.razor diff --git a/Oqtane.Client/Themes/Controls/Menu.razor b/Oqtane.Client/Themes/Controls/Theme/Menu.razor similarity index 100% rename from Oqtane.Client/Themes/Controls/Menu.razor rename to Oqtane.Client/Themes/Controls/Theme/Menu.razor diff --git a/Oqtane.Client/Themes/Controls/MenuBase.cs b/Oqtane.Client/Themes/Controls/Theme/MenuBase.cs similarity index 100% rename from Oqtane.Client/Themes/Controls/MenuBase.cs rename to Oqtane.Client/Themes/Controls/Theme/MenuBase.cs diff --git a/Oqtane.Client/Themes/Controls/MenuHorizontal.razor b/Oqtane.Client/Themes/Controls/Theme/MenuHorizontal.razor similarity index 100% rename from Oqtane.Client/Themes/Controls/MenuHorizontal.razor rename to Oqtane.Client/Themes/Controls/Theme/MenuHorizontal.razor diff --git a/Oqtane.Client/Themes/Controls/MenuItemsBase.cs b/Oqtane.Client/Themes/Controls/Theme/MenuItemsBase.cs similarity index 100% rename from Oqtane.Client/Themes/Controls/MenuItemsBase.cs rename to Oqtane.Client/Themes/Controls/Theme/MenuItemsBase.cs diff --git a/Oqtane.Client/Themes/Controls/MenuItemsHorizontal.razor b/Oqtane.Client/Themes/Controls/Theme/MenuItemsHorizontal.razor similarity index 100% rename from Oqtane.Client/Themes/Controls/MenuItemsHorizontal.razor rename to Oqtane.Client/Themes/Controls/Theme/MenuItemsHorizontal.razor diff --git a/Oqtane.Client/Themes/Controls/MenuItemsVertical.razor b/Oqtane.Client/Themes/Controls/Theme/MenuItemsVertical.razor similarity index 100% rename from Oqtane.Client/Themes/Controls/MenuItemsVertical.razor rename to Oqtane.Client/Themes/Controls/Theme/MenuItemsVertical.razor diff --git a/Oqtane.Client/Themes/Controls/MenuVertical.razor b/Oqtane.Client/Themes/Controls/Theme/MenuVertical.razor similarity index 100% rename from Oqtane.Client/Themes/Controls/MenuVertical.razor rename to Oqtane.Client/Themes/Controls/Theme/MenuVertical.razor diff --git a/Oqtane.Client/Themes/Controls/UserProfile.razor b/Oqtane.Client/Themes/Controls/Theme/UserProfile.razor similarity index 100% rename from Oqtane.Client/Themes/Controls/UserProfile.razor rename to Oqtane.Client/Themes/Controls/Theme/UserProfile.razor diff --git a/Oqtane.Client/Themes/ILayoutControl.cs b/Oqtane.Client/Themes/ILayoutControl.cs index 4aaa961a..f0873f5e 100644 --- a/Oqtane.Client/Themes/ILayoutControl.cs +++ b/Oqtane.Client/Themes/ILayoutControl.cs @@ -1,4 +1,4 @@ -namespace Oqtane.Themes +namespace Oqtane.Themes { public interface ILayoutControl { diff --git a/Oqtane.Client/Themes/LayoutBase.cs b/Oqtane.Client/Themes/LayoutBase.cs index 5d3aadfa..688f5360 100644 --- a/Oqtane.Client/Themes/LayoutBase.cs +++ b/Oqtane.Client/Themes/LayoutBase.cs @@ -1,5 +1,8 @@ -namespace Oqtane.Themes +using System; + +namespace Oqtane.Themes { + [Obsolete("This class is deprecated", false)] public abstract class LayoutBase : ThemeBase, ILayoutControl { diff --git a/Oqtane.Client/Themes/OqtaneTheme/Containers/Container.razor b/Oqtane.Client/Themes/OqtaneTheme/Containers/Container.razor new file mode 100644 index 00000000..0f1dcafe --- /dev/null +++ b/Oqtane.Client/Themes/OqtaneTheme/Containers/Container.razor @@ -0,0 +1,47 @@ +@namespace Oqtane.Themes.OqtaneTheme +@inherits ContainerBase +@inject ISettingService SettingService + +
    + @if (_title) + { +
    +
    +

    +
    +
    +
    + } + else + { + + } +
    +
    + +
    +
    +
    + +@code { + public override string Name => "Customizable Container"; + + private bool _title = true; + private string _classes = "container"; + + protected override void OnParametersSet() + { + try + { + _title = bool.Parse(SettingService.GetSetting(ModuleState.Settings, GetType().Namespace + ":Title", "true")); + _classes += " " + SettingService.GetSetting(ModuleState.Settings, GetType().Namespace + ":Background", ""); + _classes += " " + SettingService.GetSetting(ModuleState.Settings, GetType().Namespace + ":Text", ""); + _classes += " " + SettingService.GetSetting(ModuleState.Settings, GetType().Namespace + ":Border", ""); + _classes = _classes.Trim(); + } + catch + { + // error loading container settings + } + } +} \ No newline at end of file diff --git a/Oqtane.Client/Themes/OqtaneTheme/Containers/ContainerSettings.razor b/Oqtane.Client/Themes/OqtaneTheme/Containers/ContainerSettings.razor new file mode 100644 index 00000000..abf8059a --- /dev/null +++ b/Oqtane.Client/Themes/OqtaneTheme/Containers/ContainerSettings.razor @@ -0,0 +1,113 @@ +@namespace Oqtane.Themes.OqtaneTheme +@inherits ModuleBase +@implements Oqtane.Interfaces.ISettingsControl +@inject ISettingService SettingService +@attribute [OqtaneIgnore] + + + + + + + + + + + + + + + + + + +
    + + + +
    + + + +
    + + + +
    + + + +
    + +@code { + private string _title = "true"; + private string _background = ""; + private string _text = ""; + private string _border = ""; + + protected override void OnInitialized() + { + try + { + _title = SettingService.GetSetting(ModuleState.Settings, GetType().Namespace + ":Title", "true"); + _background = SettingService.GetSetting(ModuleState.Settings, GetType().Namespace + ":Background", ""); + _text = SettingService.GetSetting(ModuleState.Settings, GetType().Namespace + ":Text", ""); + _border = SettingService.GetSetting(ModuleState.Settings, GetType().Namespace + ":Border", ""); + } + catch (Exception ex) + { + ModuleInstance.AddModuleMessage(ex.Message, MessageType.Error); + } + } + + public async Task UpdateSettings() + { + try + { + var settings = ModuleState.Settings; + settings = SettingService.SetSetting(settings, GetType().Namespace + ":Title", _title); + settings = SettingService.SetSetting(settings, GetType().Namespace + ":Background", _background); + settings = SettingService.SetSetting(settings, GetType().Namespace + ":Text", _text); + settings = SettingService.SetSetting(settings, GetType().Namespace + ":Border", _border); + await SettingService.UpdateModuleSettingsAsync(settings, ModuleState.ModuleId); + } + catch (Exception ex) + { + ModuleInstance.AddModuleMessage(ex.Message, MessageType.Error); + } + } +} diff --git a/Oqtane.Client/Themes/OqtaneTheme/Containers/DefaultNoTitle.razor b/Oqtane.Client/Themes/OqtaneTheme/Containers/DefaultNoTitle.razor deleted file mode 100644 index b236edda..00000000 --- a/Oqtane.Client/Themes/OqtaneTheme/Containers/DefaultNoTitle.razor +++ /dev/null @@ -1,10 +0,0 @@ -@namespace Oqtane.Themes.OqtaneTheme -@inherits ContainerBase - -
    - -
    - -@code { - public override string Name => "No Background Color - No Title"; -} \ No newline at end of file diff --git a/Oqtane.Client/Themes/OqtaneTheme/Containers/DefaultTitle.razor b/Oqtane.Client/Themes/OqtaneTheme/Containers/DefaultTitle.razor deleted file mode 100644 index 0ba6af46..00000000 --- a/Oqtane.Client/Themes/OqtaneTheme/Containers/DefaultTitle.razor +++ /dev/null @@ -1,20 +0,0 @@ -@namespace Oqtane.Themes.OqtaneTheme -@inherits ContainerBase - -
    -
    -
    -

    -
    -
    -
    -
    -
    - -
    -
    -
    - -@code { - public override string Name => "No Background Color - With Title"; -} \ No newline at end of file diff --git a/Oqtane.Client/Themes/OqtaneTheme/Containers/PrimaryNoTitle.razor b/Oqtane.Client/Themes/OqtaneTheme/Containers/PrimaryNoTitle.razor deleted file mode 100644 index 7c7463f6..00000000 --- a/Oqtane.Client/Themes/OqtaneTheme/Containers/PrimaryNoTitle.razor +++ /dev/null @@ -1,10 +0,0 @@ -@namespace Oqtane.Themes.OqtaneTheme -@inherits ContainerBase - -
    - -
    - -@code { - public override string Name => "Primary Background Color - No Title"; -} \ No newline at end of file diff --git a/Oqtane.Client/Themes/OqtaneTheme/Containers/PrimaryTitle.razor b/Oqtane.Client/Themes/OqtaneTheme/Containers/PrimaryTitle.razor deleted file mode 100644 index 99cd8ff0..00000000 --- a/Oqtane.Client/Themes/OqtaneTheme/Containers/PrimaryTitle.razor +++ /dev/null @@ -1,20 +0,0 @@ -@namespace Oqtane.Themes.OqtaneTheme -@inherits ContainerBase - -
    -
    -
    -

    -
    -
    -
    -
    -
    - -
    -
    -
    - -@code { - public override string Name => "Primary Background Color - With Title"; -} \ No newline at end of file diff --git a/Oqtane.Client/Themes/OqtaneTheme/Containers/SecondaryNoTitle.razor b/Oqtane.Client/Themes/OqtaneTheme/Containers/SecondaryNoTitle.razor deleted file mode 100644 index 2a8a40cc..00000000 --- a/Oqtane.Client/Themes/OqtaneTheme/Containers/SecondaryNoTitle.razor +++ /dev/null @@ -1,10 +0,0 @@ -@namespace Oqtane.Themes.OqtaneTheme -@inherits ContainerBase - -
    - -
    - -@code { - public override string Name => "Secondary Background Color - No Title"; -} \ No newline at end of file diff --git a/Oqtane.Client/Themes/OqtaneTheme/Containers/SecondaryTitle.razor b/Oqtane.Client/Themes/OqtaneTheme/Containers/SecondaryTitle.razor deleted file mode 100644 index 5d033cec..00000000 --- a/Oqtane.Client/Themes/OqtaneTheme/Containers/SecondaryTitle.razor +++ /dev/null @@ -1,20 +0,0 @@ -@namespace Oqtane.Themes.OqtaneTheme -@inherits ContainerBase - -
    -
    -
    -

    -
    -
    -
    -
    -
    - -
    -
    -
    - -@code { - public override string Name => "Secondary Background Color - With Title"; -} \ No newline at end of file diff --git a/Oqtane.Client/Themes/OqtaneTheme/Layouts/MultiPane.razor b/Oqtane.Client/Themes/OqtaneTheme/Layouts/MultiPane.razor deleted file mode 100644 index 128720ce..00000000 --- a/Oqtane.Client/Themes/OqtaneTheme/Layouts/MultiPane.razor +++ /dev/null @@ -1,90 +0,0 @@ -@namespace Oqtane.Themes.OqtaneTheme -@inherits LayoutBase - -
    -
    -
    - -
    -
    -
    - -
    -
    -
    - -
    -
    -
    -
    - -
    -
    - -
    -
    -
    -
    - -
    -
    - -
    -
    - -
    -
    -
    -
    - -
    -
    - -
    -
    - -
    -
    - -
    -
    -
    -
    - -
    -
    - -
    -
    - -
    -
    -
    -
    - -
    -
    - -
    -
    -
    -
    - -
    -
    - -
    -
    -
    -
    - -
    -
    -
    - - -@code { - public override string Name => "Multiple Panes"; - - public override string Panes => "Content, Top Full Width,Top 100%,Left 50%,Right 50%,Left 33%,Center 33%,Right 33%,Left Outer 25%,Left Inner 25%,Right Inner 25%,Right Outer 25%,Left 25%,Center 50%,Right 25%,Left Sidebar 66%,Right Sidebar 33%,Left Sidebar 33%,Right Sidebar 66%,Bottom 100%,Bottom Full Width"; -} \ No newline at end of file diff --git a/Oqtane.Client/Themes/OqtaneTheme/Layouts/SinglePane.razor b/Oqtane.Client/Themes/OqtaneTheme/Layouts/SinglePane.razor deleted file mode 100644 index 6f808141..00000000 --- a/Oqtane.Client/Themes/OqtaneTheme/Layouts/SinglePane.razor +++ /dev/null @@ -1,16 +0,0 @@ -@namespace Oqtane.Themes.OqtaneTheme -@inherits LayoutBase - -
    -
    -
    - -
    -
    -
    - -@code { - public override string Name => "Single Pane"; - - public override string Panes => "Content"; -} diff --git a/Oqtane.Client/Themes/OqtaneTheme/ThemeInfo.cs b/Oqtane.Client/Themes/OqtaneTheme/ThemeInfo.cs index 39784cf3..4ac16269 100644 --- a/Oqtane.Client/Themes/OqtaneTheme/ThemeInfo.cs +++ b/Oqtane.Client/Themes/OqtaneTheme/ThemeInfo.cs @@ -1,4 +1,4 @@ -using Oqtane.Models; +using Oqtane.Models; namespace Oqtane.Themes.OqtaneTheme { @@ -7,7 +7,9 @@ namespace Oqtane.Themes.OqtaneTheme public Theme Theme => new Theme { Name = "Oqtane Theme", - Version = "1.0.0" + Version = "1.0.0", + ThemeSettingsType = "Oqtane.Themes.OqtaneTheme.ThemeSettings, Oqtane.Client", + ContainerSettingsType = "Oqtane.Themes.OqtaneTheme.ContainerSettings, Oqtane.Client" }; } } diff --git a/Oqtane.Client/Themes/OqtaneTheme/Themes/Default.razor b/Oqtane.Client/Themes/OqtaneTheme/Themes/Default.razor index 8b566485..e2ff2270 100644 --- a/Oqtane.Client/Themes/OqtaneTheme/Themes/Default.razor +++ b/Oqtane.Client/Themes/OqtaneTheme/Themes/Default.razor @@ -1,5 +1,6 @@ @namespace Oqtane.Themes.OqtaneTheme @inherits ThemeBase +@inject ISettingService SettingService
    @@ -8,20 +9,123 @@
    - +
    +
    +
    +
    + +
    +
    +
    + +
    +
    +
    + +
    +
    +
    +
    + +
    +
    + +
    +
    +
    +
    + +
    +
    + +
    +
    + +
    +
    +
    +
    + +
    +
    + +
    +
    + +
    +
    + +
    +
    +
    +
    + +
    +
    + +
    +
    + +
    +
    +
    +
    + +
    +
    + +
    +
    +
    +
    + +
    +
    + +
    +
    +
    +
    + +
    +
    +
    + + @if (_footer) + { +
    + +
    + } +
    @code { public override string Name => "Default Theme"; - public override string Panes => string.Empty; + public override string Panes => PaneNames.Admin + ",Top Full Width,Top 100%,Left 50%,Right 50%,Left 33%,Center 33%,Right 33%,Left Outer 25%,Left Inner 25%,Right Inner 25%,Right Outer 25%,Left 25%,Center 50%,Right 25%,Left Sidebar 66%,Right Sidebar 33%,Left Sidebar 33%,Right Sidebar 66%,Bottom 100%,Bottom Full Width,Footer"; public override List Resources => new List() - { +{ new Resource { ResourceType = ResourceType.Stylesheet, Url = "https://stackpath.bootstrapcdn.com/bootswatch/4.5.0/cyborg/bootstrap.min.css", Integrity = "sha384-GKugkVcT8wqoh3M8z1lqHbU+g6j498/ZT/zuXbepz7Dc09/otQZxTimkEMTkRWHP", CrossOrigin = "anonymous" }, new Resource { ResourceType = ResourceType.Stylesheet, Url = ThemePath() + "Theme.css" }, new Resource { ResourceType = ResourceType.Script, Bundle = "Bootstrap", Url = "https://code.jquery.com/jquery-3.5.1.slim.min.js", Integrity = "sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj", CrossOrigin = "anonymous" }, new Resource { ResourceType = ResourceType.Script, Bundle = "Bootstrap", Url = "https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js", Integrity = "sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo", CrossOrigin = "anonymous" }, new Resource { ResourceType = ResourceType.Script, Bundle = "Bootstrap", Url = "https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/js/bootstrap.min.js", Integrity = "sha384-OgVRvuATP1z7JjHLkuOU7Xw704+h835Lr+6QL9UvYjZE3Ipu6Tp75j7Bh/kR0JKI", CrossOrigin = "anonymous" } }; + + private bool _footer = false; + + protected override void OnParametersSet() + { + try + { + _footer = bool.Parse(SettingService.GetSetting(PageState.Page.Settings, GetType().Namespace + ":Footer", "false")); + } + catch + { + // error loading theme settings + } + } + } diff --git a/Oqtane.Client/Themes/OqtaneTheme/Themes/ThemeSettings.razor b/Oqtane.Client/Themes/OqtaneTheme/Themes/ThemeSettings.razor new file mode 100644 index 00000000..baaa940f --- /dev/null +++ b/Oqtane.Client/Themes/OqtaneTheme/Themes/ThemeSettings.razor @@ -0,0 +1,49 @@ +@namespace Oqtane.Themes.OqtaneTheme +@inherits ModuleBase +@implements Oqtane.Interfaces.ISettingsControl +@inject ISettingService SettingService +@attribute [OqtaneIgnore] + + + + + + +
    + + + +
    + +@code { + private string _footer = "false"; + + protected override void OnInitialized() + { + try + { + _footer = SettingService.GetSetting(PageState.Page.Settings, GetType().Namespace + ":Footer", "false"); + } + catch (Exception ex) + { + ModuleInstance.AddModuleMessage(ex.Message, MessageType.Error); + } + } + + public async Task UpdateSettings() + { + try + { + var settings = PageState.Page.Settings; + settings = SettingService.SetSetting(settings, GetType().Namespace + ":Footer", _footer); + await SettingService.UpdatePageSettingsAsync(settings, PageState.Page.PageId); + } + catch (Exception ex) + { + ModuleInstance.AddModuleMessage(ex.Message, MessageType.Error); + } + } +} diff --git a/Oqtane.Client/UI/ContainerBuilder.razor b/Oqtane.Client/UI/ContainerBuilder.razor index 174f251f..a48dfe0f 100644 --- a/Oqtane.Client/UI/ContainerBuilder.razor +++ b/Oqtane.Client/UI/ContainerBuilder.razor @@ -1,6 +1,6 @@ @namespace Oqtane.UI - + @if (_useadminborder) {
    @@ -14,22 +14,20 @@ @code { - private Module _moduleState; private bool _useadminborder = false; [CascadingParameter] protected PageState PageState { get; set; } [Parameter] - public Module Module { get; set; } + public Module ModuleState { get; set; } RenderFragment DynamicComponent { get; set; } protected override void OnParametersSet() { - _moduleState = Module; // passed in from Pane component - string container = _moduleState.ContainerType; - if (PageState.ModuleId != -1 && _moduleState.UseAdminContainer) + string container = ModuleState.ContainerType; + if (PageState.ModuleId != -1 && ModuleState.UseAdminContainer) { container = (!string.IsNullOrEmpty(PageState.Site.AdminContainerType)) ? PageState.Site.AdminContainerType : Constants.DefaultAdminContainer; } diff --git a/Oqtane.Client/UI/Pane.razor b/Oqtane.Client/UI/Pane.razor index fe71f45e..fd99bd9c 100644 --- a/Oqtane.Client/UI/Pane.razor +++ b/Oqtane.Client/UI/Pane.razor @@ -124,7 +124,7 @@ else private void CreateComponent(RenderTreeBuilder builder, Module module) { builder.OpenComponent(0, Type.GetType(Constants.ContainerComponent)); - builder.AddAttribute(1, "Module", module); + builder.AddAttribute(1, "ModuleState", module); builder.SetKey(module.PageModuleId); builder.CloseComponent(); } diff --git a/Oqtane.Client/UI/PaneLayout.razor b/Oqtane.Client/UI/PaneLayout.razor index 95e7a776..d91733fe 100644 --- a/Oqtane.Client/UI/PaneLayout.razor +++ b/Oqtane.Client/UI/PaneLayout.razor @@ -1,25 +1,5 @@ -@namespace Oqtane.UI - -@DynamicComponent +@namespace Oqtane.UI @code { - [CascadingParameter] - protected PageState PageState { get; set; } - - RenderFragment DynamicComponent { get; set; } - - protected override void OnParametersSet() - { - DynamicComponent = builder => - { - var layoutType = Type.GetType(PageState.Page.LayoutType); - if (layoutType == null) - { - // fallback - layoutType = Type.GetType(Constants.DefaultLayout); - } - builder.OpenComponent(0, layoutType); - builder.CloseComponent(); - }; - } + // panelayouts are deprecated - this component is included for backward compatibility } \ No newline at end of file diff --git a/Oqtane.Client/UI/SiteRouter.razor b/Oqtane.Client/UI/SiteRouter.razor index 70bda7df..66aa79d6 100644 --- a/Oqtane.Client/UI/SiteRouter.razor +++ b/Oqtane.Client/UI/SiteRouter.razor @@ -384,21 +384,15 @@ page.ThemeType = site.DefaultThemeType; } - if (string.IsNullOrEmpty(page.LayoutType)) - { - page.LayoutType = site.DefaultLayoutType; - } - page.Panes = new List(); page.Resources = new List(); - string panes = ""; + string panes = PaneNames.Admin; Type themetype = Type.GetType(page.ThemeType); if (themetype == null) { // fallback page.ThemeType = Constants.DefaultTheme; - page.LayoutType = Constants.DefaultLayout; themetype = Type.GetType(Constants.DefaultTheme); } if (themetype != null) @@ -406,24 +400,13 @@ var themeobject = Activator.CreateInstance(themetype) as IThemeControl; if (themeobject != null) { - panes = themeobject.Panes; + if (!string.IsNullOrEmpty(themeobject.Panes)) + { + panes = themeobject.Panes; + } page.Resources = ManagePageResources(page.Resources, themeobject.Resources); } } - - if (!string.IsNullOrEmpty(page.LayoutType)) - { - Type layouttype = Type.GetType(page.LayoutType); - if (layouttype != null) - { - var layoutobject = Activator.CreateInstance(layouttype) as IThemeControl; - if (layoutobject != null) - { - panes = layoutobject.Panes; - } - } - } - page.Panes = panes.Replace(";", ",").Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries).ToList(); } catch diff --git a/Oqtane.Client/wwwroot/Themes/Softvision.DemoTheme/Theme.css b/Oqtane.Client/wwwroot/Themes/Softvision.DemoTheme/Theme.css new file mode 100644 index 00000000..c77bb42e --- /dev/null +++ b/Oqtane.Client/wwwroot/Themes/Softvision.DemoTheme/Theme.css @@ -0,0 +1,83 @@ +/* Oqtane Styles */ + +body { + padding-top: 7rem; +} + +.controls { + z-index: 2000; + padding-top: 15px; + padding-bottom: 15px; + margin-right: 10px; +} + +.app-menu .nav-item { + font-size: 0.9rem; + padding-bottom: 0.5rem; +} + +.app-menu .nav-item a { + border-radius: 4px; + height: 3rem; + display: flex; + align-items: center; + line-height: 3rem; +} + +.app-menu .nav-item a.active { + background-color: rgba(255,255,255,0.25); + color: white; +} + +.app-menu .nav-item a:hover { + background-color: rgba(255,255,255,0.1); + color: white; +} + +.app-menu .nav-link .oi { + width: 1.5rem; + font-size: 1.1rem; + vertical-align: text-top; + top: -2px; +} + +.navbar-toggler { + background-color: rgba(255, 255, 255, 0.1); + margin-left: auto; +} + +div.app-moduleactions a.dropdown-toggle, div.app-moduleactions div.dropdown-menu { + color:#000000; +} + +@media (max-width: 767px) { + + .app-menu { + width: 100% + } + + .navbar { + position: fixed; + top: 60px; + width: 100%; + } + + .controls { + height: 60px; + top: 15px; + position: fixed; + top: 0px; + width: 100%; + background-color: rgb(0, 0, 0); + } + + .controls-group { + float: right; + margin-right: 25px; + } + + .content { + position: relative; + top: 60px; + } +} diff --git a/Oqtane.Server/Controllers/InstallationController.cs b/Oqtane.Server/Controllers/InstallationController.cs index 2d8491d6..46c4106f 100644 --- a/Oqtane.Server/Controllers/InstallationController.cs +++ b/Oqtane.Server/Controllers/InstallationController.cs @@ -12,6 +12,7 @@ using Oqtane.Modules; using Oqtane.Shared; using Oqtane.Themes; using Microsoft.Extensions.Caching.Memory; +using System.Collections.Generic; namespace Oqtane.Controllers { @@ -180,6 +181,7 @@ namespace Oqtane.Controllers } } } + return memoryStream.ToArray(); } }); diff --git a/Oqtane.Server/Controllers/PageController.cs b/Oqtane.Server/Controllers/PageController.cs index aab9c23d..81d3018b 100644 --- a/Oqtane.Server/Controllers/PageController.cs +++ b/Oqtane.Server/Controllers/PageController.cs @@ -1,4 +1,4 @@ -using System.Collections.Generic; +using System.Collections.Generic; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Authorization; using Oqtane.Models; @@ -19,16 +19,18 @@ namespace Oqtane.Controllers private readonly IPageRepository _pages; private readonly IModuleRepository _modules; private readonly IPageModuleRepository _pageModules; + private readonly ISettingRepository _settings; private readonly IUserPermissions _userPermissions; private readonly ITenantResolver _tenants; private readonly ISyncManager _syncManager; private readonly ILogManager _logger; - public PageController(IPageRepository pages, IModuleRepository modules, IPageModuleRepository pageModules, IUserPermissions userPermissions, ITenantResolver tenants, ISyncManager syncManager, ILogManager logger) + public PageController(IPageRepository pages, IModuleRepository modules, IPageModuleRepository pageModules, ISettingRepository settings, IUserPermissions userPermissions, ITenantResolver tenants, ISyncManager syncManager, ILogManager logger) { _pages = pages; _modules = modules; _pageModules = pageModules; + _settings = settings; _userPermissions = userPermissions; _tenants = tenants; _syncManager = syncManager; @@ -39,11 +41,15 @@ namespace Oqtane.Controllers [HttpGet] public IEnumerable Get(string siteid) { + List settings = _settings.GetSettings(EntityNames.Page).ToList(); + List pages = new List(); foreach (Page page in _pages.GetPages(int.Parse(siteid))) { if (_userPermissions.IsAuthorized(User,PermissionNames.View, page.Permissions)) { + page.Settings = settings.Where(item => item.EntityId == page.PageId) + .ToDictionary(setting => setting.SettingName, setting => setting.SettingValue); pages.Add(page); } } @@ -65,6 +71,8 @@ namespace Oqtane.Controllers } if (_userPermissions.IsAuthorized(User,PermissionNames.View, page.Permissions)) { + page.Settings = _settings.GetSettings(EntityNames.Page, page.PageId) + .ToDictionary(setting => setting.SettingName, setting => setting.SettingValue); return page; } else @@ -84,6 +92,8 @@ namespace Oqtane.Controllers { if (_userPermissions.IsAuthorized(User,PermissionNames.View, page.Permissions)) { + page.Settings = _settings.GetSettings(EntityNames.Page, page.PageId) + .ToDictionary(setting => setting.SettingName, setting => setting.SettingValue); return page; } else @@ -164,7 +174,6 @@ namespace Oqtane.Controllers page.IsNavigation = false; page.Url = ""; page.ThemeType = parent.ThemeType; - page.LayoutType = parent.LayoutType; page.DefaultContainerType = parent.DefaultContainerType; page.Icon = parent.Icon; page.Permissions = new List { diff --git a/Oqtane.Server/Infrastructure/DatabaseManager.cs b/Oqtane.Server/Infrastructure/DatabaseManager.cs index 9ee98e25..bb1028a0 100644 --- a/Oqtane.Server/Infrastructure/DatabaseManager.cs +++ b/Oqtane.Server/Infrastructure/DatabaseManager.cs @@ -90,7 +90,6 @@ namespace Oqtane.Infrastructure install.HostName = UserNames.Host; install.SiteTemplate = GetInstallationConfig(SettingKeys.SiteTemplateKey, Constants.DefaultSiteTemplate); install.DefaultTheme = GetInstallationConfig(SettingKeys.DefaultThemeKey, Constants.DefaultTheme); - install.DefaultLayout = GetInstallationConfig(SettingKeys.DefaultLayoutKey, Constants.DefaultLayout); install.DefaultContainer = GetInstallationConfig(SettingKeys.DefaultContainerKey, Constants.DefaultContainer); install.SiteName = Constants.DefaultSite; install.IsNewTenant = true; @@ -122,10 +121,6 @@ namespace Oqtane.Infrastructure if (string.IsNullOrEmpty(install.DefaultTheme)) { install.DefaultTheme = GetInstallationConfig(SettingKeys.DefaultThemeKey, Constants.DefaultTheme); - if (string.IsNullOrEmpty(install.DefaultLayout)) - { - install.DefaultLayout = GetInstallationConfig(SettingKeys.DefaultLayoutKey, Constants.DefaultLayout); - } } if (string.IsNullOrEmpty(install.DefaultContainer)) { @@ -438,7 +433,6 @@ namespace Oqtane.Infrastructure Name = install.SiteName, LogoFileId = null, DefaultThemeType = install.DefaultTheme, - DefaultLayoutType = install.DefaultLayout, DefaultContainerType = install.DefaultContainer, SiteTemplateType = install.SiteTemplate }; diff --git a/Oqtane.Server/Infrastructure/Interfaces/ILocalizationManager.cs b/Oqtane.Server/Infrastructure/Interfaces/ILocalizationManager.cs index fa20eef4..d85f0923 100644 --- a/Oqtane.Server/Infrastructure/Interfaces/ILocalizationManager.cs +++ b/Oqtane.Server/Infrastructure/Interfaces/ILocalizationManager.cs @@ -1,4 +1,4 @@ -namespace Oqtane.Infrastructure +namespace Oqtane.Infrastructure { public interface ILocalizationManager { diff --git a/Oqtane.Server/Infrastructure/Localization/LocalizationOptions.cs b/Oqtane.Server/Infrastructure/Localization/LocalizationOptions.cs index 6330130e..97755ab8 100644 --- a/Oqtane.Server/Infrastructure/Localization/LocalizationOptions.cs +++ b/Oqtane.Server/Infrastructure/Localization/LocalizationOptions.cs @@ -1,9 +1,7 @@ -namespace Oqtane.Infrastructure +namespace Oqtane.Infrastructure { public class LocalizationOptions { public string DefaultCulture { get; set; } - - public string[] SupportedCultures { get; set; } } } diff --git a/Oqtane.Server/Infrastructure/LocalizationManager.cs b/Oqtane.Server/Infrastructure/LocalizationManager.cs index 22b4ca79..d52bda8f 100644 --- a/Oqtane.Server/Infrastructure/LocalizationManager.cs +++ b/Oqtane.Server/Infrastructure/LocalizationManager.cs @@ -1,4 +1,6 @@ -using System.Collections; +using System.Collections.Generic; +using System.IO; +using System.Reflection; using Microsoft.Extensions.Options; using Oqtane.Shared; @@ -22,8 +24,23 @@ namespace Oqtane.Infrastructure : _localizationOptions.DefaultCulture; public string[] GetSupportedCultures() - => _localizationOptions.SupportedCultures.IsNullOrEmpty() - ? SupportedCultures - : _localizationOptions.SupportedCultures; + { + List cultures = new List(); + foreach(var file in Directory.EnumerateFiles(Path.GetDirectoryName(Assembly.GetEntryAssembly().Location), "*.resources.dll", SearchOption.AllDirectories)) + { + if (!cultures.Contains(Path.GetFileName(Path.GetDirectoryName(file)))) + { + cultures.Add(Path.GetFileName(Path.GetDirectoryName(file))); + } + } + if (cultures.Count == 0) + { + return SupportedCultures; + } + else + { + return cultures.ToArray(); + } + } } } diff --git a/Oqtane.Server/Infrastructure/UpgradeManager.cs b/Oqtane.Server/Infrastructure/UpgradeManager.cs index fc435f10..5919be0b 100644 --- a/Oqtane.Server/Infrastructure/UpgradeManager.cs +++ b/Oqtane.Server/Infrastructure/UpgradeManager.cs @@ -91,7 +91,14 @@ namespace Oqtane.Infrastructure var internalTemplatePath = Utilities.PathCombine(_environment.WebRootPath, "Modules", "Templates", "Internal", Path.DirectorySeparatorChar.ToString()); if (Directory.Exists(internalTemplatePath)) { - Directory.Delete(internalTemplatePath, true); + try + { + Directory.Delete(internalTemplatePath, true); + } + catch + { + // error deleting directory + } } } diff --git a/Oqtane.Server/Oqtane.Server.csproj b/Oqtane.Server/Oqtane.Server.csproj index b871e0d5..ef341003 100644 --- a/Oqtane.Server/Oqtane.Server.csproj +++ b/Oqtane.Server/Oqtane.Server.csproj @@ -41,6 +41,7 @@ + diff --git a/Oqtane.Server/Repository/SiteRepository.cs b/Oqtane.Server/Repository/SiteRepository.cs index af4f2b06..b376b470 100644 --- a/Oqtane.Server/Repository/SiteRepository.cs +++ b/Oqtane.Server/Repository/SiteRepository.cs @@ -745,7 +745,6 @@ namespace Oqtane.Repository Url = "", IsNavigation = pagetemplate.IsNavigation, ThemeType = "", - LayoutType = "", DefaultContainerType = "", Icon = pagetemplate.Icon, Permissions = pagetemplate.PagePermissions, diff --git a/Oqtane.Server/Repository/ThemeRepository.cs b/Oqtane.Server/Repository/ThemeRepository.cs index f85b7cd7..c3fc91ee 100644 --- a/Oqtane.Server/Repository/ThemeRepository.cs +++ b/Oqtane.Server/Repository/ThemeRepository.cs @@ -63,7 +63,7 @@ namespace Oqtane.Repository { // Check if type should be ignored if (themeControlType.IsOqtaneIgnore() || - themeControlType.GetInterfaces().Contains(typeof(ILayoutControl)) || + themeControlType.GetInterfaces().Contains(typeof(ILayoutControl)) || // deprecated themeControlType.GetInterfaces().Contains(typeof(IContainerControl))) continue; // create namespace root typename @@ -98,7 +98,6 @@ namespace Oqtane.Repository // set internal properties theme.ThemeName = qualifiedThemeType; theme.Themes = new List(); - theme.Layouts = new List(); theme.Containers = new List(); theme.AssemblyName = assembly.FullName.Split(",")[0]; themes.Add(theme); @@ -113,27 +112,10 @@ namespace Oqtane.Repository TypeName = themeControlType.FullName + ", " + themeControlType.Assembly.GetName().Name, Name = theme.Name + " - " + ((string.IsNullOrEmpty(themecontrolobject.Name)) ? Utilities.GetTypeNameLastSegment(themeControlType.FullName, 0) : themecontrolobject.Name), Thumbnail = themecontrolobject.Thumbnail, - Panes = themecontrolobject.Panes + Panes = (!string.IsNullOrEmpty(themecontrolobject.Panes)) ? themecontrolobject.Panes : PaneNames.Admin } ); - // layouts - Type[] layouttypes = themeTypes - .Where(item => item.GetInterfaces().Contains(typeof(ILayoutControl))).ToArray(); - foreach (Type layouttype in layouttypes) - { - var layoutobject = Activator.CreateInstance(layouttype) as IThemeControl; - theme.Layouts.Add( - new ThemeControl - { - TypeName = layouttype.FullName + ", " + themeControlType.Assembly.GetName().Name, - Name = (string.IsNullOrEmpty(layoutobject.Name)) ? Utilities.GetTypeNameLastSegment(layouttype.FullName, 0) : layoutobject.Name, - Thumbnail = layoutobject.Thumbnail, - Panes = layoutobject.Panes - } - ); - } - // containers Type[] containertypes = themeTypes .Where(item => item.GetInterfaces().Contains(typeof(IContainerControl))).ToArray(); diff --git a/Oqtane.Server/Scripts/Tenant.02.00.02.03.sql b/Oqtane.Server/Scripts/Tenant.02.00.02.03.sql new file mode 100644 index 00000000..ae34cf33 --- /dev/null +++ b/Oqtane.Server/Scripts/Tenant.02.00.02.03.sql @@ -0,0 +1,31 @@ +/* + +Version 2.0.2 Tenant migration script + +*/ + +ALTER TABLE [dbo].[Setting] ALTER COLUMN [SettingName] [nvarchar](200) NOT NULL +GO + +ALTER TABLE [dbo].[Site] + DROP COLUMN DefaultLayoutType +GO + +ALTER TABLE [dbo].[Page] + DROP COLUMN LayoutType +GO + +UPDATE [dbo].[Site] SET DefaultContainerType = 'Oqtane.Themes.OqtaneTheme.Container, Oqtane.Client' WHERE DefaultContainerType = 'Oqtane.Themes.OqtaneTheme.DefaultTitle, Oqtane.Client'; +GO +UPDATE [dbo].[Site] SET DefaultContainerType = 'Oqtane.Themes.OqtaneTheme.Container, Oqtane.Client' WHERE DefaultContainerType = 'Oqtane.Themes.OqtaneTheme.DefaultNoTitle, Oqtane.Client'; +GO + +UPDATE [dbo].[Page] SET DefaultContainerType = 'Oqtane.Themes.OqtaneTheme.Container, Oqtane.Client' WHERE DefaultContainerType = 'Oqtane.Themes.OqtaneTheme.DefaultTitle, Oqtane.Client'; +GO +UPDATE [dbo].[Page] SET DefaultContainerType = 'Oqtane.Themes.OqtaneTheme.Container, Oqtane.Client' WHERE DefaultContainerType = 'Oqtane.Themes.OqtaneTheme.DefaultNoTitle, Oqtane.Client'; +GO + +UPDATE [dbo].[PageModule] SET ContainerType = 'Oqtane.Themes.OqtaneTheme.Container, Oqtane.Client' WHERE ContainerType = 'Oqtane.Themes.OqtaneTheme.DefaultTitle, Oqtane.Client'; +GO +UPDATE [dbo].[PageModule] SET ContainerType = 'Oqtane.Themes.OqtaneTheme.Container, Oqtane.Client' WHERE ContainerType = 'Oqtane.Themes.OqtaneTheme.DefaultNoTitle, Oqtane.Client'; +GO diff --git a/Oqtane.Server/Startup.cs b/Oqtane.Server/Startup.cs index 1e744c01..d76e1ef0 100644 --- a/Oqtane.Server/Startup.cs +++ b/Oqtane.Server/Startup.cs @@ -41,7 +41,6 @@ namespace Oqtane Configuration = builder.Build(); _supportedCultures = localizationManager.GetSupportedCultures(); - _runtime = (Configuration.GetSection("Runtime").Value == "WebAssembly") ? Runtime.WebAssembly : Runtime.Server; //add possibility to switch off swagger on production. diff --git a/Oqtane.Server/wwwroot/Modules/Templates/External/Client/Modules/[Owner].[Module]/Edit.razor b/Oqtane.Server/wwwroot/Modules/Templates/External/Client/Modules/[Owner].[Module]/Edit.razor index 9858a044..b866069a 100644 --- a/Oqtane.Server/wwwroot/Modules/Templates/External/Client/Modules/[Owner].[Module]/Edit.razor +++ b/Oqtane.Server/wwwroot/Modules/Templates/External/Client/Modules/[Owner].[Module]/Edit.razor @@ -74,7 +74,7 @@ { try { - if (string.IsNullOrEmpty(_name)) + if (!string.IsNullOrEmpty(_name)) { if (PageState.Action == "Add") { diff --git a/Oqtane.Server/wwwroot/Modules/Templates/External/Client/Modules/[Owner].[Module]/Index.razor b/Oqtane.Server/wwwroot/Modules/Templates/External/Client/Modules/[Owner].[Module]/Index.razor index 275b3ec8..4f5e0f37 100644 --- a/Oqtane.Server/wwwroot/Modules/Templates/External/Client/Modules/[Owner].[Module]/Index.razor +++ b/Oqtane.Server/wwwroot/Modules/Templates/External/Client/Modules/[Owner].[Module]/Index.razor @@ -36,40 +36,6 @@ else } } - - -
    -[Module] Module Created Successfully. Use Edit Mode To Add A [Module]. You Can Access The Files At The Following Locations:

    -[RootPath]Client\
    -- [Owner].[Module].Client.csproj - client project
    -- _Imports.razor - global imports for module components
    -- Edit.razor - component for adding or editing content
    -- Index.razor - main component for your module **the content you are reading is in this file**
    -- ModuleInfo.cs - implements IModule interface to provide configuration settings for your module
    -- Settings.razor - component for managing module settings
    -- Services\I[Module]Service.cs - interface for defining service API methods
    -- Services\[Module]Service.cs - implements service API interface methods

    -[RootPath]Package\
    -- [Owner].[Module].nuspec - nuget manifest for packaging module
    -- [Owner].[Module].Package.csproj - packaging project
    -- debug.cmd - copies assemblies to Oqtane bin folder when in Debug mode
    -- release.cmd - creates nuget package and deploys to Oqtane wwwroot/modules folder when in Release mode

    -[RootPath]Server\
    -- [Owner].[Module].Server.csproj - server project
    -- Controllers\[Module]Controller.cs - API methods implemented using a REST pattern
    -- Manager\[Module]Manager.cs - implements optional module interfaces for features such as import/export of content
    -- Repository\I[Module]Repository.cs - interface for defining repository methods
    -- Repository\[Module]Respository.cs - implements repository interface methods for data access using EF Core
    -- Repository\[Module]Context.cs - provides a DB Context for data access
    -- Scripts\[Owner].[Module].1.0.0.sql - database schema definition script
    -- Scripts\[Owner].[Module].Uninstall.sql - database uninstall script
    -- wwwroot\Module.css - module style sheet

    -[RootPath]Shared\
    -- [Owner].[Module].csproj - shared project
    -- Models\[Module].cs - model definition

    - - - @code { public override List Resources => new List() { diff --git a/Oqtane.Server/wwwroot/Themes/Oqtane.Themes.OqtaneTheme/Theme.css b/Oqtane.Server/wwwroot/Themes/Oqtane.Themes.OqtaneTheme/Theme.css index b8056c79..a4c5f957 100644 --- a/Oqtane.Server/wwwroot/Themes/Oqtane.Themes.OqtaneTheme/Theme.css +++ b/Oqtane.Server/wwwroot/Themes/Oqtane.Themes.OqtaneTheme/Theme.css @@ -1,4 +1,4 @@ -/* Oqtane Styles */ +/* Oqtane Styles */ body { padding-top: 7rem; @@ -50,6 +50,13 @@ div.app-moduleactions a.dropdown-toggle, div.app-moduleactions div.dropdown-menu color:#ffffff; } +.footer { + padding-top: 15px; + min-height: 40px; + text-align: center; + color: #ffffff; +} + @media (max-width: 767px) { .app-menu { diff --git a/Oqtane.Server/wwwroot/Themes/Templates/External/Client/Themes/Theme1.razor b/Oqtane.Server/wwwroot/Themes/Templates/External/Client/Themes/Theme1.razor index 7ffefe5f..c9d137bb 100644 --- a/Oqtane.Server/wwwroot/Themes/Templates/External/Client/Themes/Theme1.razor +++ b/Oqtane.Server/wwwroot/Themes/Templates/External/Client/Themes/Theme1.razor @@ -8,10 +8,11 @@
    +
    - +
    @@ -89,12 +90,13 @@
    + @code { public override string Name => "Theme1"; - public override string Panes => "Content,Top Full Width,Top 100%,Left 50%,Right 50%,Left 33%,Center 33%,Right 33%,Left Outer 25%,Left Inner 25%,Right Inner 25%,Right Outer 25%,Left 25%,Center 50%,Right 25%,Left Sidebar 66%,Right Sidebar 33%,Left Sidebar 33%,Right Sidebar 66%,Bottom 100%,Bottom Full Width"; + public override string Panes => PaneNames.Admin + ",Top Full Width,Top 100%,Left 50%,Right 50%,Left 33%,Center 33%,Right 33%,Left Outer 25%,Left Inner 25%,Right Inner 25%,Right Outer 25%,Left 25%,Center 50%,Right 25%,Left Sidebar 66%,Right Sidebar 33%,Left Sidebar 33%,Right Sidebar 66%,Bottom 100%,Bottom Full Width"; public override List Resources => new List() { diff --git a/Oqtane.Server/wwwroot/Themes/Templates/External/Client/wwwroot/Themes/[Owner].[Theme]/Theme.css b/Oqtane.Server/wwwroot/Themes/Templates/External/Client/wwwroot/Themes/[Owner].[Theme]/Theme.css index b8056c79..e3a02d94 100644 --- a/Oqtane.Server/wwwroot/Themes/Templates/External/Client/wwwroot/Themes/[Owner].[Theme]/Theme.css +++ b/Oqtane.Server/wwwroot/Themes/Templates/External/Client/wwwroot/Themes/[Owner].[Theme]/Theme.css @@ -47,7 +47,7 @@ body { } div.app-moduleactions a.dropdown-toggle, div.app-moduleactions div.dropdown-menu { - color:#ffffff; + color:#000000; } @media (max-width: 767px) { diff --git a/Oqtane.Server/wwwroot/_content/Placeholder.txt b/Oqtane.Server/wwwroot/_content/Placeholder.txt new file mode 100644 index 00000000..5a324d79 --- /dev/null +++ b/Oqtane.Server/wwwroot/_content/Placeholder.txt @@ -0,0 +1,11 @@ +The _content folder should only contain static resources from shared razor component libraries (RCLs). Static resources can be extracted from shared RCL Nuget packages by executing a Publish task on the module's Server project to a local folder and copying the files from the _content folder which is created. Each shared RCL would have its own appropriately named subfolder within the module's _content folder. + +ie. + +/_content + /Radzen.Blazor + /css + /fonts + /syncfusion.blazor + /scripts + /styles diff --git a/Oqtane.Shared/Models/ModuleDefinition.cs b/Oqtane.Shared/Models/ModuleDefinition.cs index 0fd8b892..a13a342a 100644 --- a/Oqtane.Shared/Models/ModuleDefinition.cs +++ b/Oqtane.Shared/Models/ModuleDefinition.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.ComponentModel.DataAnnotations.Schema; namespace Oqtane.Models @@ -21,6 +21,7 @@ namespace Oqtane.Models ControlTypeRoutes = ""; ReleaseVersions = ""; DefaultAction = ""; + SettingsType = ""; Runtimes = ""; Template = ""; } @@ -60,6 +61,8 @@ namespace Oqtane.Models public string ReleaseVersions { get; set; } [NotMapped] public string DefaultAction { get; set; } + [NotMapped] + public string SettingsType { get; set; } // added in 2.0.2 // internal properties [NotMapped] diff --git a/Oqtane.Shared/Models/Page.cs b/Oqtane.Shared/Models/Page.cs index 0960a52a..5b553c63 100644 --- a/Oqtane.Shared/Models/Page.cs +++ b/Oqtane.Shared/Models/Page.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations.Schema; @@ -15,7 +15,6 @@ namespace Oqtane.Models public int Order { get; set; } public string Url { get; set; } public string ThemeType { get; set; } - public string LayoutType { get; set; } public string DefaultContainerType { get; set; } public string Icon { get; set; } public bool IsNavigation { get; set; } @@ -37,12 +36,19 @@ namespace Oqtane.Models [NotMapped] public string Permissions { get; set; } [NotMapped] + public Dictionary Settings { get; set; } + [NotMapped] public int Level { get; set; } [NotMapped] public bool HasChildren { get; set; } - [Obsolete("This property is obsolete", false)] + [Obsolete("This property is deprecated", false)] [NotMapped] public bool EditMode { get; set; } + + [Obsolete("This property is deprecated", false)] + [NotMapped] + public string LayoutType { get; set; } + } } diff --git a/Oqtane.Shared/Models/Site.cs b/Oqtane.Shared/Models/Site.cs index 5adf1318..2ce878fc 100644 --- a/Oqtane.Shared/Models/Site.cs +++ b/Oqtane.Shared/Models/Site.cs @@ -11,7 +11,6 @@ namespace Oqtane.Models public int? LogoFileId { get; set; } public int? FaviconFileId { get; set; } public string DefaultThemeType { get; set; } - public string DefaultLayoutType { get; set; } public string DefaultContainerType { get; set; } public string AdminContainerType { get; set; } public bool PwaIsEnabled { get; set; } @@ -30,5 +29,9 @@ namespace Oqtane.Models [NotMapped] public string SiteTemplateType { get; set; } + + [NotMapped] + [Obsolete("This property is deprecated.", false)] + public string DefaultLayoutType { get; set; } } } diff --git a/Oqtane.Shared/Models/Theme.cs b/Oqtane.Shared/Models/Theme.cs index 398cc537..72abd0dd 100644 --- a/Oqtane.Shared/Models/Theme.cs +++ b/Oqtane.Shared/Models/Theme.cs @@ -25,17 +25,22 @@ namespace Oqtane.Models public string Contact { get; set; } public string License { get; set; } public string Dependencies { get; set; } + public string ThemeSettingsType { get; set; } + public string ContainerSettingsType { get; set; } + + // internal properties public string AssemblyName { get; set; } public List Themes { get; set; } - public List Layouts { get; set; } public List Containers { get; set; } public string Template { get; set; } - //[Obsolete("This property is obsolete. Use Themes instead.", false)] + [Obsolete("This property is obsolete. Use Themes instead.", false)] public string ThemeControls { get; set; } - //[Obsolete("This property is obsolete. Use Layouts instead.", false)] + [Obsolete("This property is obsolete. Use Layouts instead.", false)] public string PaneLayouts { get; set; } - //[Obsolete("This property is obsolete. Use Containers instead.", false)] + [Obsolete("This property is obsolete. Use Containers instead.", false)] public string ContainerControls { get; set; } + [Obsolete("This property is obsolete.", false)] + public List Layouts { get; set; } } } diff --git a/Oqtane.Shared/Shared/Constants.cs b/Oqtane.Shared/Shared/Constants.cs index 89d0e9a7..9fde30d5 100644 --- a/Oqtane.Shared/Shared/Constants.cs +++ b/Oqtane.Shared/Shared/Constants.cs @@ -12,8 +12,9 @@ namespace Oqtane.Shared { public const string ContainerComponent = "Oqtane.UI.ContainerBuilder, Oqtane.Client"; public const string DefaultTheme = "Oqtane.Themes.OqtaneTheme.Default, Oqtane.Client"; - public const string DefaultLayout = "Oqtane.Themes.OqtaneTheme.SinglePane, Oqtane.Client"; - public const string DefaultContainer = "Oqtane.Themes.OqtaneTheme.DefaultTitle, Oqtane.Client"; + [Obsolete("DefaultLayout is deprecated")] + public const string DefaultLayout = ""; + public const string DefaultContainer = "Oqtane.Themes.OqtaneTheme.Container, Oqtane.Client"; public const string DefaultAdminContainer = "Oqtane.Themes.AdminContainer, Oqtane.Client"; public const string ActionToken = "{Action}"; diff --git a/Oqtane.Shared/Shared/InstallConfig.cs b/Oqtane.Shared/Shared/InstallConfig.cs index 7658e97d..9aa81eda 100644 --- a/Oqtane.Shared/Shared/InstallConfig.cs +++ b/Oqtane.Shared/Shared/InstallConfig.cs @@ -12,7 +12,6 @@ namespace Oqtane.Shared public string HostName { get; set; } public string SiteTemplate { get; set; } public string DefaultTheme { get; set; } - public string DefaultLayout { get; set; } public string DefaultContainer { get; set; } public string DefaultAdminContainer { get; set; } } diff --git a/Oqtane.Shared/Shared/PaneNames.cs b/Oqtane.Shared/Shared/PaneNames.cs index 7806f821..16209b8a 100644 --- a/Oqtane.Shared/Shared/PaneNames.cs +++ b/Oqtane.Shared/Shared/PaneNames.cs @@ -1,5 +1,5 @@ namespace Oqtane.Shared { public class PaneNames { - public const string Admin = "Content"; + public const string Admin = "Admin"; } }