commit
8069d838d5
|
@ -11,26 +11,28 @@
|
|||
}
|
||||
<AuthorizeView>
|
||||
<NotAuthorized>
|
||||
<div class="container Oqtane-Modules-Admin-Login">
|
||||
<div class="form-group">
|
||||
<label for="Username" class="control-label">@Localizer["Username:"] </label>
|
||||
<input type="text" name="Username" class="form-control username" placeholder="Username" @bind="@_username" id="Username" />
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="Password" class="control-label">@Localizer["Password:"] </label>
|
||||
<input type="password" name="Password" class="form-control password" placeholder="Password" @bind="@_password" id="Password" />
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class="form-check form-check-inline">
|
||||
<label class="form-check-label" for="Remember">@Localizer["Remember Me?"]</label>
|
||||
<input type="checkbox" class="form-check-input" name="Remember" @bind="@_remember" id="Remember" />
|
||||
<form @ref="login" class="@(validated ? "was-validated" : "needs-validation")" novalidate>
|
||||
<div class="container Oqtane-Modules-Admin-Login" @onkeypress="@(e => KeyPressed(e))">
|
||||
<div class="form-group">
|
||||
<label for="Username" class="control-label">@Localizer["Username:"] </label>
|
||||
<input type="text" @ref="username" name="Username" class="form-control username" placeholder="Username" @bind="@_username" id="Username" required />
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="Password" class="control-label">@Localizer["Password:"] </label>
|
||||
<input type="password" name="Password" class="form-control password" placeholder="Password" @bind="@_password" id="Password" required />
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class="form-check form-check-inline">
|
||||
<label class="form-check-label" for="Remember">@Localizer["Remember Me?"]</label>
|
||||
<input type="checkbox" class="form-check-input" name="Remember" @bind="@_remember" id="Remember" />
|
||||
</div>
|
||||
</div>
|
||||
<button type="button" class="btn btn-primary" @onclick="Login">@Localizer["Login"]</button>
|
||||
<button type="button" class="btn btn-secondary" @onclick="Cancel">@Localizer["Cancel"]</button>
|
||||
<br /><br />
|
||||
<button type="button" class="btn btn-secondary" @onclick="Forgot">@Localizer["Forgot Password"]</button>
|
||||
</div>
|
||||
<button type="button" class="btn btn-primary" @onclick="Login">@Localizer["Login"]</button>
|
||||
<button type="button" class="btn btn-secondary" @onclick="Cancel">@Localizer["Cancel"]</button>
|
||||
<br /><br />
|
||||
<button type="button" class="btn btn-secondary" @onclick="Forgot">@Localizer["Forgot Password"]</button>
|
||||
</div>
|
||||
</form>
|
||||
</NotAuthorized>
|
||||
</AuthorizeView>
|
||||
|
||||
|
@ -41,6 +43,10 @@
|
|||
private string _username = string.Empty;
|
||||
private string _password = string.Empty;
|
||||
private bool _remember = false;
|
||||
private bool validated = false;
|
||||
|
||||
private ElementReference login;
|
||||
private ElementReference username;
|
||||
|
||||
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Anonymous;
|
||||
|
||||
|
@ -80,52 +86,68 @@
|
|||
}
|
||||
}
|
||||
|
||||
protected override async Task OnAfterRenderAsync(bool firstRender)
|
||||
{
|
||||
if (firstRender)
|
||||
{
|
||||
await username.FocusAsync();
|
||||
}
|
||||
}
|
||||
|
||||
private async Task Login()
|
||||
{
|
||||
if (PageState.Runtime == Oqtane.Shared.Runtime.Server)
|
||||
validated = true;
|
||||
var interop = new Interop(JSRuntime);
|
||||
if (await interop.FormValid(login))
|
||||
{
|
||||
// server-side Blazor
|
||||
var user = new User();
|
||||
user.SiteId = PageState.Site.SiteId;
|
||||
user.Username = _username;
|
||||
user.Password = _password;
|
||||
user = await UserService.LoginUserAsync(user, false, false);
|
||||
|
||||
if (user.IsAuthenticated)
|
||||
if (PageState.Runtime == Oqtane.Shared.Runtime.Server)
|
||||
{
|
||||
await logger.LogInformation("Login Successful For Username {Username}", _username);
|
||||
// complete the login on the server so that the cookies are set correctly on SignalR
|
||||
var interop = new Interop(JSRuntime);
|
||||
string antiforgerytoken = await interop.GetElementByName("__RequestVerificationToken");
|
||||
var fields = new { __RequestVerificationToken = antiforgerytoken, username = _username, password = _password, remember = _remember, returnurl = _returnUrl };
|
||||
await interop.SubmitForm($"/{PageState.Alias.AliasId}/pages/login/", fields);
|
||||
// server-side Blazor
|
||||
var user = new User();
|
||||
user.SiteId = PageState.Site.SiteId;
|
||||
user.Username = _username;
|
||||
user.Password = _password;
|
||||
user = await UserService.LoginUserAsync(user, false, false);
|
||||
|
||||
if (user.IsAuthenticated)
|
||||
{
|
||||
await logger.LogInformation("Login Successful For Username {Username}", _username);
|
||||
// complete the login on the server so that the cookies are set correctly on SignalR
|
||||
string antiforgerytoken = await interop.GetElementByName("__RequestVerificationToken");
|
||||
var fields = new { __RequestVerificationToken = antiforgerytoken, username = _username, password = _password, remember = _remember, returnurl = _returnUrl };
|
||||
await interop.SubmitForm($"/{PageState.Alias.AliasId}/pages/login/", fields);
|
||||
}
|
||||
else
|
||||
{
|
||||
await logger.LogInformation("Login Failed For Username {Username}", _username);
|
||||
AddModuleMessage(Localizer["Login Failed. Please Remember That Passwords Are Case Sensitive And User Accounts Require Verification When They Are Initially Created So You May Wish To Check Your Email."], MessageType.Error);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
await logger.LogInformation("Login Failed For Username {Username}", _username);
|
||||
AddModuleMessage(Localizer["Login Failed. Please Remember That Passwords Are Case Sensitive And User Accounts Require Email Verification When They Initially Created."], MessageType.Error);
|
||||
// client-side Blazor
|
||||
var user = new User();
|
||||
user.SiteId = PageState.Site.SiteId;
|
||||
user.Username = _username;
|
||||
user.Password = _password;
|
||||
user = await UserService.LoginUserAsync(user, true, _remember);
|
||||
if (user.IsAuthenticated)
|
||||
{
|
||||
await logger.LogInformation("Login Successful For Username {Username}", _username);
|
||||
var authstateprovider = (IdentityAuthenticationStateProvider)ServiceProvider.GetService(typeof(IdentityAuthenticationStateProvider));
|
||||
authstateprovider.NotifyAuthenticationChanged();
|
||||
NavigationManager.NavigateTo(NavigateUrl(_returnUrl, "reload"));
|
||||
}
|
||||
else
|
||||
{
|
||||
await logger.LogInformation("Login Failed For Username {Username}", _username);
|
||||
AddModuleMessage(Localizer["Login Failed. Please Remember That Passwords Are Case Sensitive And User Accounts Require Verification When They Are Initially Created So You May Wish To Check Your Email."], MessageType.Error);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// client-side Blazor
|
||||
var user = new User();
|
||||
user.SiteId = PageState.Site.SiteId;
|
||||
user.Username = _username;
|
||||
user.Password = _password;
|
||||
user = await UserService.LoginUserAsync(user, true, _remember);
|
||||
if (user.IsAuthenticated)
|
||||
{
|
||||
await logger.LogInformation("Login Successful For Username {Username}", _username);
|
||||
var authstateprovider = (IdentityAuthenticationStateProvider)ServiceProvider.GetService(typeof(IdentityAuthenticationStateProvider));
|
||||
authstateprovider.NotifyAuthenticationChanged();
|
||||
NavigationManager.NavigateTo(NavigateUrl(_returnUrl, "reload"));
|
||||
}
|
||||
else
|
||||
{
|
||||
await logger.LogInformation("Login Failed For Username {Username}", _username);
|
||||
AddModuleMessage(Localizer["Login Failed. Please Remember That Passwords Are Case Sensitive And User Accounts Require Verification When They Are Initially Created So You May Wish To Check Your Email."], MessageType.Error);
|
||||
}
|
||||
AddModuleMessage(Localizer["Please Provide Your Username And Password"], MessageType.Warning);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -157,4 +179,12 @@
|
|||
|
||||
StateHasChanged();
|
||||
}
|
||||
|
||||
private async Task KeyPressed(KeyboardEventArgs e)
|
||||
{
|
||||
if (e.Code == "Enter" || e.Code == "NumpadEnter")
|
||||
{
|
||||
await Login();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -100,7 +100,7 @@ else
|
|||
|
||||
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Host;
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
protected override async Task OnParametersSetAsync()
|
||||
{
|
||||
try
|
||||
{
|
||||
|
@ -110,9 +110,7 @@ else
|
|||
|
||||
if (string.IsNullOrEmpty(_moduledefinitionname))
|
||||
{
|
||||
_owner = ModuleState.Title;
|
||||
_module = ModuleState.Title;
|
||||
_description = ModuleState.Title;
|
||||
AddModuleMessage(Localizer["Please Note That The Module Creator Is Only Intended To Be Used In A Development Environment"], MessageType.Info);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -162,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)
|
||||
|
|
158
Oqtane.Client/Modules/Admin/ModuleDefinitions/Create.razor
Normal file
158
Oqtane.Client/Modules/Admin/ModuleDefinitions/Create.razor
Normal file
|
@ -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<Index> Localizer
|
||||
@using System.Text.RegularExpressions
|
||||
@using System.IO;
|
||||
|
||||
@if (_systeminfo != null && _templates != null)
|
||||
{
|
||||
<table class="table table-borderless">
|
||||
<tr>
|
||||
<td>
|
||||
<Label For="owner" HelpText="Enter the name of the organization who is developing this module. It should not contain spaces or punctuation." ResourceKey="OwnerName">Owner Name: </Label>
|
||||
</td>
|
||||
<td>
|
||||
<input id="owner" class="form-control" @bind="@_owner" />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<Label For="module" HelpText="Enter a name for this module. It should not contain spaces or punctuation." ResourceKey="ModuleName">Module Name: </Label>
|
||||
</td>
|
||||
<td>
|
||||
<input id="module" class="form-control" @bind="@_module" />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<Label For="description" HelpText="Enter a short description for the module" ResourceKey="Description">Description: </Label>
|
||||
</td>
|
||||
<td>
|
||||
<textarea id="description" class="form-control" @bind="@_description" rows="3"></textarea>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<Label For="template" HelpText="Select a module template. Templates are located in the wwwroot/Modules/Templates folder on the server." ResourceKey="Template">Template: </Label>
|
||||
</td>
|
||||
<td>
|
||||
<select id="template" class="form-control" @onchange="(e => TemplateChanged(e))">
|
||||
<option value="-"><@Localizer["Select Template"]></option>
|
||||
@foreach (string template in _templates)
|
||||
{
|
||||
<option value="@template">@template</option>
|
||||
}
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<Label For="reference" HelpText="Select a framework reference version" ResourceKey="FrameworkReference">Framework Reference: </Label>
|
||||
</td>
|
||||
<td>
|
||||
<select id="reference" class="form-control" @bind="@_reference">
|
||||
@foreach (string version in Constants.ReleaseVersions.Split(','))
|
||||
{
|
||||
if (Version.Parse(version).CompareTo(Version.Parse("2.0.0")) >= 0)
|
||||
{
|
||||
<option value="@(version)">@(version)</option>
|
||||
}
|
||||
}
|
||||
<option value="local">@Localizer["Local Version"]</option>
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
@if (!string.IsNullOrEmpty(_location))
|
||||
{
|
||||
<tr>
|
||||
<td>
|
||||
<Label For="location" HelpText="Location where the module will be created" ResourceKey="Location">Location: </Label>
|
||||
</td>
|
||||
<td>
|
||||
<input id="module" class="form-control" @bind="@_location" readonly />
|
||||
</td>
|
||||
</tr>
|
||||
}
|
||||
</table>
|
||||
<button type="button" class="btn btn-success" @onclick="CreateModule">@Localizer["Create Module"]</button>
|
||||
<NavLink class="btn btn-secondary" href="@NavigateUrl()">@Localizer["Cancel"]</NavLink>
|
||||
}
|
||||
|
||||
@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<string, string> _systeminfo;
|
||||
private List<string> _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 <a href=\"{0}\">Restart</a> 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();
|
||||
}
|
||||
}
|
|
@ -12,6 +12,8 @@
|
|||
else
|
||||
{
|
||||
<ActionLink Action="Add" Text="Install Module" ResourceKey="InstallModule" />
|
||||
@((MarkupString)" ")
|
||||
<ActionLink Action="Create" Text="Create Module" ResourceKey="CreateModule" />
|
||||
|
||||
<Pager Items="@_moduleDefinitions">
|
||||
<Header>
|
||||
|
@ -25,17 +27,17 @@ else
|
|||
<td><ActionLink Action="Edit" Parameters="@($"id=" + context.ModuleDefinitionId.ToString())" ResourceKey="EditModule" /></td>
|
||||
<td>
|
||||
@if (context.AssemblyName != "Oqtane.Client")
|
||||
{
|
||||
{
|
||||
<ActionDialog Header="Delete Module" Message="@Localizer["Are You Sure You Wish To Delete The {0} Module?", context.Name]" Action="Delete" Security="SecurityAccessLevel.Host" Class="btn btn-danger" OnClick="@(async () => await DeleteModule(context))" ResourceKey="DeleteModule" />
|
||||
}
|
||||
}
|
||||
</td>
|
||||
<td>@context.Name</td>
|
||||
<td>@context.Version</td>
|
||||
<td>
|
||||
@if (UpgradeAvailable(context.ModuleDefinitionName, context.Version))
|
||||
{
|
||||
{
|
||||
<button type="button" class="btn btn-success" @onclick=@(async () => await DownloadModule(context.ModuleDefinitionName, context.Version))>@Localizer["Upgrade"]</button>
|
||||
}
|
||||
}
|
||||
</td>
|
||||
</Row>
|
||||
</Pager>
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
@inject IStringLocalizer<Settings> Localizer
|
||||
|
||||
<TabStrip>
|
||||
<TabPanel Name="Settings" Heading="Module Settings" ResourceKey="ModuleSettings">
|
||||
<TabPanel Name="Settings" Heading="Settings" ResourceKey="Settings">
|
||||
@if (_containers != null)
|
||||
{
|
||||
<table class="table table-borderless">
|
||||
|
@ -26,7 +26,6 @@
|
|||
</td>
|
||||
<td>
|
||||
<select id="container" class="form-control" @bind="@_containerType">
|
||||
<option value="-"><@Localizer["Inherit From Page Or Site"]></option>
|
||||
@foreach (var container in _containers)
|
||||
{
|
||||
<option value="@container.TypeName">@container.Name</option>
|
||||
|
@ -47,7 +46,7 @@
|
|||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<Label For="page" HelpText="The page that the module is on" ResourceKey="Page">Page: </Label>
|
||||
<Label For="page" HelpText="The page that the module is located on" ResourceKey="Page">Page: </Label>
|
||||
</td>
|
||||
<td>
|
||||
<select id="page" class="form-control" @bind="@_pageId">
|
||||
|
@ -76,10 +75,16 @@
|
|||
</table>
|
||||
}
|
||||
</TabPanel>
|
||||
@if (_settingsModuleType != null)
|
||||
@if (_moduleSettingsType != null)
|
||||
{
|
||||
<TabPanel Name="ModuleSettings" Heading="@_settingstitle" ResourceKey="Module Settings">
|
||||
@DynamicComponent
|
||||
<TabPanel Name="ModuleSettings" Heading="@_moduleSettingsTitle" ResourceKey="ModuleSettings">
|
||||
@ModuleSettingsComponent
|
||||
</TabPanel>
|
||||
}
|
||||
@if (_containerSettingsType != null)
|
||||
{
|
||||
<TabPanel Name="ContainerSettings" Heading="Container Settings" ResourceKey="ContainerSettings">
|
||||
@ContainerSettingsComponent
|
||||
</TabPanel>
|
||||
}
|
||||
</TabStrip>
|
||||
|
@ -87,6 +92,10 @@
|
|||
<NavLink class="btn btn-secondary" href="@NavigateUrl()">@Localizer["Cancel"]</NavLink>
|
||||
|
||||
@code {
|
||||
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Edit;
|
||||
public override string Title => "Module Settings";
|
||||
|
||||
private List<Theme> _themes;
|
||||
private List<ThemeControl> _containers = new List<ThemeControl>();
|
||||
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());
|
||||
}
|
||||
|
||||
|
|
|
@ -102,7 +102,6 @@
|
|||
</td>
|
||||
<td>
|
||||
<select id="Theme" class="form-control" value="@_themetype" @onchange="(e => ThemeChanged(e))">
|
||||
<option value="-"><@Localizer["Inherit From Site"]></option>
|
||||
@foreach (var theme in _themes)
|
||||
{
|
||||
<option value="@theme.TypeName">@theme.Name</option>
|
||||
|
@ -110,37 +109,13 @@
|
|||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
@if (_layouts.Count > 0)
|
||||
{
|
||||
<tr>
|
||||
<td>
|
||||
<Label For="Layout" HelpText="Select a layout for the page (if the selected theme supports it)" ResourceKey="Layout">Layout: </Label>
|
||||
</td>
|
||||
<td>
|
||||
<select id="Layout" class="form-control" @bind="@_layouttype">
|
||||
<option value="-"><@Localizer["Inherit From Site"]></option>
|
||||
@foreach (var layout in _layouts)
|
||||
{
|
||||
if (layout.TypeName == _layouttype)
|
||||
{
|
||||
<option value="@(layout.TypeName)" selected>@(layout.Name)</option>
|
||||
}
|
||||
else
|
||||
{
|
||||
<option value="@(layout.TypeName)">@(layout.Name)</option>
|
||||
}
|
||||
}
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
}
|
||||
<tr>
|
||||
<td>
|
||||
<Label For="defaultContainer" HelpText="Select the default container for the page" ResourceKey="DefaultContainer">Default Container: </Label>
|
||||
</td>
|
||||
<td>
|
||||
<select id="defaultContainer" class="form-control" @bind="@_containertype">
|
||||
<option value="-"><@Localizer["Inherit From Site"]></option>
|
||||
<option value="-"><@Localizer["Select Container"]></option>
|
||||
@foreach (var container in _containers)
|
||||
{
|
||||
<option value="@container.TypeName">@container.Name</option>
|
||||
|
@ -180,14 +155,21 @@
|
|||
</tr>
|
||||
</table>
|
||||
</TabPanel>
|
||||
@if (_themeSettingsType != null)
|
||||
{
|
||||
<TabPanel Name="ThemeSettings" Heading="Theme Settings" ResourceKey="ThemeSettings">
|
||||
@ThemeSettingsComponent
|
||||
</TabPanel>
|
||||
}
|
||||
</TabStrip>
|
||||
<button type="button" class="btn btn-success" @onclick="SavePage">@Localizer["Save"]</button>
|
||||
<button type="button" class="btn btn-secondary" @onclick="Cancel">@Localizer["Cancel"]</button>
|
||||
|
||||
@code {
|
||||
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Admin;
|
||||
|
||||
private List<Theme> _themeList;
|
||||
private List<ThemeControl> _themes = new List<ThemeControl>();
|
||||
private List<ThemeControl> _layouts = new List<ThemeControl>();
|
||||
private List<ThemeControl> _containers = new List<ThemeControl>();
|
||||
private List<Page> _pageList;
|
||||
private string _name;
|
||||
|
@ -200,25 +182,28 @@
|
|||
private string _isnavigation = "True";
|
||||
private string _url;
|
||||
private string _ispersonalizable = "False";
|
||||
private string _themetype = "-";
|
||||
private string _layouttype = "-";
|
||||
private string _containertype = "-";
|
||||
private string _themetype = string.Empty;
|
||||
private string _containertype = string.Empty;
|
||||
private string _icon = string.Empty;
|
||||
private string _permissions = string.Empty;
|
||||
private PermissionGrid _permissionGrid;
|
||||
|
||||
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Admin;
|
||||
private Type _themeSettingsType;
|
||||
private object _themeSettings;
|
||||
private RenderFragment ThemeSettingsComponent { get; set; }
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
try
|
||||
{
|
||||
_themeList = await ThemeService.GetThemesAsync();
|
||||
_themes = ThemeService.GetThemeControls(_themeList);
|
||||
_themetype = PageState.Site.DefaultThemeType;
|
||||
_containers = ThemeService.GetContainerControls(_themeList, _themetype);
|
||||
_containertype = PageState.Site.DefaultContainerType;
|
||||
_pageList = PageState.Pages;
|
||||
_children = PageState.Pages.Where(item => item.ParentId == null).ToList();
|
||||
|
||||
_themes = ThemeService.GetThemeControls(_themeList);
|
||||
_permissions = string.Empty;
|
||||
ThemeSettings();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
@ -267,18 +252,9 @@
|
|||
try
|
||||
{
|
||||
_themetype = (string)e.Value;
|
||||
if (_themetype != "-")
|
||||
{
|
||||
_layouts = ThemeService.GetLayoutControls(_themeList, _themetype);
|
||||
_containers = ThemeService.GetContainerControls(_themeList, _themetype);
|
||||
}
|
||||
else
|
||||
{
|
||||
_layouts = new List<ThemeControl>();
|
||||
_containers = new List<ThemeControl>();
|
||||
}
|
||||
_layouttype = "-";
|
||||
_containers = ThemeService.GetContainerControls(_themeList, _themetype);
|
||||
_containertype = "-";
|
||||
ThemeSettings();
|
||||
StateHasChanged();
|
||||
}
|
||||
catch (Exception ex)
|
||||
|
@ -288,12 +264,31 @@
|
|||
}
|
||||
}
|
||||
|
||||
private void ThemeSettings()
|
||||
{
|
||||
_themeSettingsType = null;
|
||||
var theme = _themeList.FirstOrDefault(item => item.Themes.Any(themecontrol => themecontrol.TypeName.Equals(_themetype)));
|
||||
if (theme != null && !string.IsNullOrEmpty(theme.ThemeSettingsType))
|
||||
{
|
||||
_themeSettingsType = Type.GetType(theme.ThemeSettingsType);
|
||||
if (_themeSettingsType != null)
|
||||
{
|
||||
ThemeSettingsComponent = builder =>
|
||||
{
|
||||
builder.OpenComponent(0, _themeSettingsType);
|
||||
builder.AddComponentReferenceCapture(1, inst => { _themeSettings = Convert.ChangeType(inst, _themeSettingsType); });
|
||||
builder.CloseComponent();
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private async Task SavePage()
|
||||
{
|
||||
Page page = null;
|
||||
try
|
||||
{
|
||||
if (_name != string.Empty && !string.IsNullOrEmpty(_themetype) && (_layouts.Count == 0 || _layouttype != "-"))
|
||||
if (_name != string.Empty && !string.IsNullOrEmpty(_themetype) && _containertype != "-")
|
||||
{
|
||||
page = new Page();
|
||||
page.SiteId = PageState.Page.SiteId;
|
||||
|
@ -360,11 +355,6 @@
|
|||
{
|
||||
page.ThemeType = string.Empty;
|
||||
}
|
||||
page.LayoutType = (_layouttype != "-") ? _layouttype : string.Empty;
|
||||
if (!string.IsNullOrEmpty(page.LayoutType) && page.LayoutType == PageState.Site.DefaultLayoutType)
|
||||
{
|
||||
page.LayoutType = string.Empty;
|
||||
}
|
||||
page.DefaultContainerType = (_containertype != "-") ? _containertype : string.Empty;
|
||||
if (!string.IsNullOrEmpty(page.DefaultContainerType) && page.DefaultContainerType == PageState.Site.DefaultContainerType)
|
||||
{
|
||||
|
@ -390,7 +380,7 @@
|
|||
}
|
||||
else
|
||||
{
|
||||
AddModuleMessage(Localizer["You Must Provide Page Name And Theme/Layout"], MessageType.Warning);
|
||||
AddModuleMessage(Localizer["You Must Provide Page Name, Theme, and Container"], MessageType.Warning);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
@namespace Oqtane.Modules.Admin.Pages
|
||||
@using Oqtane.Interfaces
|
||||
@inherits ModuleBase
|
||||
@inject NavigationManager NavigationManager
|
||||
@inject IPageService PageService
|
||||
|
@ -27,7 +28,10 @@
|
|||
<option value="-1"><@Localizer["Site Root"]></option>
|
||||
@foreach (Page page in _pageList)
|
||||
{
|
||||
<option value="@(page.PageId)">@(new string('-', page.Level * 2))@(page.Name)</option>
|
||||
if (page.PageId != _pageId)
|
||||
{
|
||||
<option value="@(page.PageId)">@(new string('-', page.Level * 2))@(page.Name)</option>
|
||||
}
|
||||
}
|
||||
</select>
|
||||
</td>
|
||||
|
@ -106,7 +110,6 @@
|
|||
</td>
|
||||
<td>
|
||||
<select id="Theme" class="form-control" value="@_themetype" @onchange="(e => ThemeChanged(e))">
|
||||
<option value="-"><@Localizer["Inherit From Site"]></option>
|
||||
@foreach (var theme in _themes)
|
||||
{
|
||||
<option value="@theme.TypeName">@theme.Name</option>
|
||||
|
@ -114,37 +117,13 @@
|
|||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
@if (_layouts.Count > 0)
|
||||
{
|
||||
<tr>
|
||||
<td>
|
||||
<Label For="Layout" HelpText="Select a layout for the page (if the selected theme supports it)" ResourceKey="Layout">Layout: </Label>
|
||||
</td>
|
||||
<td>
|
||||
<select id="Layout" class="form-control" @bind="@_layouttype">
|
||||
<option value="-"><@Localizer["Inherit From Site"]></option>
|
||||
@foreach (var layout in _layouts)
|
||||
{
|
||||
if (layout.TypeName == _layouttype)
|
||||
{
|
||||
<option value="@(layout.TypeName)" selected>@(layout.Name)</option>
|
||||
}
|
||||
else
|
||||
{
|
||||
<option value="@(layout.TypeName)">@(layout.Name)</option>
|
||||
}
|
||||
}
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
}
|
||||
<tr>
|
||||
<td>
|
||||
<Label For="defaultContainer" HelpText="Select the default container for the page" ResourceKey="DefaultContainer">Default Container: </Label>
|
||||
</td>
|
||||
<td>
|
||||
<select id="defaultContainer" class="form-control" @bind="@_containertype">
|
||||
<option value="-"><@Localizer["Inherit From Site"]></option>
|
||||
<option value="-"><@Localizer["Select Container"]></option>
|
||||
@foreach (var container in _containers)
|
||||
{
|
||||
<option value="@container.TypeName">@container.Name</option>
|
||||
|
@ -189,14 +168,21 @@
|
|||
</table>
|
||||
}
|
||||
</TabPanel>
|
||||
@if (_themeSettingsType != null)
|
||||
{
|
||||
<TabPanel Name="ThemeSettings" Heading="Theme Settings" ResourceKey="ThemeSettings">
|
||||
@ThemeSettingsComponent
|
||||
</TabPanel>
|
||||
}
|
||||
</TabStrip>
|
||||
<button type="button" class="btn btn-success" @onclick="SavePage">@Localizer["Save"]</button>
|
||||
<button type="button" class="btn btn-secondary" @onclick="Cancel">@Localizer["Cancel"]</button>
|
||||
|
||||
@code {
|
||||
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Admin;
|
||||
|
||||
private List<Theme> _themeList;
|
||||
private List<ThemeControl> _themes = new List<ThemeControl>();
|
||||
private List<ThemeControl> _layouts = new List<ThemeControl>();
|
||||
private List<ThemeControl> _containers = new List<ThemeControl>();
|
||||
private List<Page> _pageList;
|
||||
private int _pageId;
|
||||
|
@ -211,8 +197,7 @@
|
|||
private string _isnavigation;
|
||||
private string _url;
|
||||
private string _ispersonalizable;
|
||||
private string _themetype = "-";
|
||||
private string _layouttype = "-";
|
||||
private string _themetype;
|
||||
private string _containertype = "-";
|
||||
private string _icon;
|
||||
private string _permissions = null;
|
||||
|
@ -222,12 +207,10 @@
|
|||
private DateTime _modifiedon;
|
||||
private string _deletedby;
|
||||
private DateTime? _deletedon;
|
||||
|
||||
#pragma warning disable 649
|
||||
private PermissionGrid _permissionGrid;
|
||||
#pragma warning restore 649
|
||||
|
||||
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Admin;
|
||||
private Type _themeSettingsType;
|
||||
private object _themeSettings;
|
||||
private RenderFragment ThemeSettingsComponent { get; set; }
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
|
@ -266,21 +249,15 @@
|
|||
_url = page.Url;
|
||||
_ispersonalizable = page.IsPersonalizable.ToString();
|
||||
_themetype = page.ThemeType;
|
||||
if (_themetype == PageState.Site.DefaultThemeType)
|
||||
if (string.IsNullOrEmpty(_themetype))
|
||||
{
|
||||
_themetype = "-";
|
||||
_themetype = PageState.Site.DefaultThemeType;
|
||||
}
|
||||
_layouts = ThemeService.GetLayoutControls(_themeList, page.ThemeType);
|
||||
_layouttype = page.LayoutType;
|
||||
if (_layouttype == PageState.Site.DefaultLayoutType)
|
||||
{
|
||||
_layouttype = "-";
|
||||
}
|
||||
_containers = ThemeService.GetContainerControls(_themeList, page.ThemeType);
|
||||
_containers = ThemeService.GetContainerControls(_themeList, _themetype);
|
||||
_containertype = page.DefaultContainerType;
|
||||
if (string.IsNullOrEmpty(_containertype))
|
||||
{
|
||||
_containertype = "-";
|
||||
_containertype = PageState.Site.DefaultContainerType;
|
||||
}
|
||||
_icon = page.Icon;
|
||||
_permissions = page.Permissions;
|
||||
|
@ -290,6 +267,8 @@
|
|||
_modifiedon = page.ModifiedOn;
|
||||
_deletedby = page.DeletedBy;
|
||||
_deletedon = page.DeletedOn;
|
||||
|
||||
ThemeSettings();
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
|
@ -347,18 +326,9 @@
|
|||
try
|
||||
{
|
||||
_themetype = (string)e.Value;
|
||||
if (_themetype != "-")
|
||||
{
|
||||
_layouts = ThemeService.GetLayoutControls(_themeList, _themetype);
|
||||
_containers = ThemeService.GetContainerControls(_themeList, _themetype);
|
||||
}
|
||||
else
|
||||
{
|
||||
_layouts = new List<ThemeControl>();
|
||||
_containers = new List<ThemeControl>();
|
||||
}
|
||||
_layouttype = "-";
|
||||
_containers = ThemeService.GetContainerControls(_themeList, _themetype);
|
||||
_containertype = "-";
|
||||
ThemeSettings();
|
||||
StateHasChanged();
|
||||
}
|
||||
catch (Exception ex)
|
||||
|
@ -368,12 +338,31 @@
|
|||
}
|
||||
}
|
||||
|
||||
private void ThemeSettings()
|
||||
{
|
||||
_themeSettingsType = null;
|
||||
var theme = _themeList.FirstOrDefault(item => item.Themes.Any(themecontrol => themecontrol.TypeName.Equals(_themetype)));
|
||||
if (theme != null && !string.IsNullOrEmpty(theme.ThemeSettingsType))
|
||||
{
|
||||
_themeSettingsType = Type.GetType(theme.ThemeSettingsType);
|
||||
if (_themeSettingsType != null)
|
||||
{
|
||||
ThemeSettingsComponent = builder =>
|
||||
{
|
||||
builder.OpenComponent(0, _themeSettingsType);
|
||||
builder.AddComponentReferenceCapture(1, inst => { _themeSettings = Convert.ChangeType(inst, _themeSettingsType); });
|
||||
builder.CloseComponent();
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private async Task SavePage()
|
||||
{
|
||||
Page page = null;
|
||||
try
|
||||
{
|
||||
if (_name != string.Empty)
|
||||
if (_name != string.Empty && !string.IsNullOrEmpty(_themetype) && _containertype != "-")
|
||||
{
|
||||
page = PageState.Pages.FirstOrDefault(item => item.PageId == _pageId);
|
||||
string currentPath = page.Path;
|
||||
|
@ -442,11 +431,6 @@
|
|||
{
|
||||
page.ThemeType = string.Empty;
|
||||
}
|
||||
page.LayoutType = (_layouttype != "-") ? _layouttype : string.Empty;
|
||||
if (!string.IsNullOrEmpty(page.LayoutType) && page.LayoutType == PageState.Site.DefaultLayoutType)
|
||||
{
|
||||
page.LayoutType = string.Empty;
|
||||
}
|
||||
page.DefaultContainerType = (_containertype != "-") ? _containertype : string.Empty;
|
||||
if (!string.IsNullOrEmpty(page.DefaultContainerType) && page.DefaultContainerType == PageState.Site.DefaultContainerType)
|
||||
{
|
||||
|
@ -478,6 +462,11 @@
|
|||
}
|
||||
}
|
||||
|
||||
if (_themeSettingsType != null && _themeSettings is ISettingsControl themeSettingsControl)
|
||||
{
|
||||
await themeSettingsControl.UpdateSettings();
|
||||
}
|
||||
|
||||
await logger.LogInformation("Page Saved {Page}", page);
|
||||
if (PageState.QueryString.ContainsKey("cp"))
|
||||
{
|
||||
|
@ -490,7 +479,7 @@
|
|||
}
|
||||
else
|
||||
{
|
||||
AddModuleMessage(Localizer["You Must Provide Page Name"], MessageType.Warning);
|
||||
AddModuleMessage(Localizer["You Must Provide Page Name, Theme, and Container"], MessageType.Warning);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
|
|
|
@ -91,23 +91,6 @@
|
|||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
@if (_layouts.Count > 0)
|
||||
{
|
||||
<tr>
|
||||
<td>
|
||||
<Label For="defaultLayout" HelpText="Select the sites default layout" ResourceKey="DefaultLayout">Default Layout: </Label>
|
||||
</td>
|
||||
<td>
|
||||
<select id="defaultLayout" class="form-control" @bind="@_layouttype">
|
||||
<option value="-"><@Localizer["Select Layout"]></option>
|
||||
@foreach (var layout in _layouts)
|
||||
{
|
||||
<option value="@(layout.TypeName)">@(layout.Name)</option>
|
||||
}
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
}
|
||||
<tr>
|
||||
<td>
|
||||
<Label For="defaultContainer" HelpText="Select the default container for the site" ResourceKey="DefaultContainer">Default Container: </Label>
|
||||
|
@ -244,7 +227,6 @@
|
|||
private bool _initialized = false;
|
||||
private List<Theme> _themeList;
|
||||
private List<ThemeControl> _themes = new List<ThemeControl>();
|
||||
private List<ThemeControl> _layouts = new List<ThemeControl>();
|
||||
private List<ThemeControl> _containers = new List<ThemeControl>();
|
||||
private string _name = string.Empty;
|
||||
private List<Tenant> _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<ThemeControl>();
|
||||
_containers = new List<ThemeControl>();
|
||||
}
|
||||
_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)
|
||||
|
|
|
@ -47,23 +47,6 @@ else
|
|||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
@if (_layouts.Count > 0)
|
||||
{
|
||||
<tr>
|
||||
<td>
|
||||
<Label For="defaultLayout" HelpText="Select the default layout for the site" ResourceKey="DefaultLayout">Default Layout: </Label>
|
||||
</td>
|
||||
<td>
|
||||
<select id="defaultLayout" class="form-control" @bind="@_layouttype">
|
||||
<option value="-"><@Localizer["Select Layout"]></option>
|
||||
@foreach (var layout in _layouts)
|
||||
{
|
||||
<option value="@(layout.TypeName)">@(layout.Name)</option>
|
||||
}
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
}
|
||||
<tr>
|
||||
<td>
|
||||
<Label For="defaultContainer" HelpText="Select the default container for the site" ResourceKey="DefaultContainer">Default Container: </Label>
|
||||
|
@ -219,7 +202,6 @@ else
|
|||
@code {
|
||||
private List<Theme> _themeList;
|
||||
private List<ThemeControl> _themes = new List<ThemeControl>();
|
||||
private List<ThemeControl> _layouts = new List<ThemeControl>();
|
||||
private List<ThemeControl> _containers = new List<ThemeControl>();
|
||||
private List<SiteTemplate> _siteTemplates;
|
||||
private List<Tenant> _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<ThemeControl>();
|
||||
_containers = new List<ThemeControl>();
|
||||
}
|
||||
_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<string>();
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -40,23 +40,6 @@
|
|||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
@if (_layouts.Count > 0)
|
||||
{
|
||||
<tr>
|
||||
<td>
|
||||
<Label For="defaultLayout" HelpText="Select the default layout for the site" ResourceKey="DefaultLayout">Default Layout: </Label>
|
||||
</td>
|
||||
<td>
|
||||
<select id="defaultLayout" class="form-control" @bind="@_layouttype">
|
||||
<option value="-"><@Localizer["Select Layout"]></option>
|
||||
@foreach (var layout in _layouts)
|
||||
{
|
||||
<option value="@(layout.TypeName)">@(layout.Name)</option>
|
||||
}
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
}
|
||||
<tr>
|
||||
<td>
|
||||
<Label For="defaultContainer" HelpText="Select the default container for the site" ResourceKey="DefaultContainer">Default Container: </Label>
|
||||
|
@ -127,14 +110,12 @@
|
|||
private bool _initialized = false;
|
||||
private List<Theme> _themeList;
|
||||
private List<ThemeControl> _themes = new List<ThemeControl>();
|
||||
private List<ThemeControl> _layouts = new List<ThemeControl>();
|
||||
private List<ThemeControl> _containers = new List<ThemeControl>();
|
||||
private Alias _alias;
|
||||
private string _name = string.Empty;
|
||||
private List<Alias> _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<ThemeControl>();
|
||||
_containers = new List<ThemeControl>();
|
||||
}
|
||||
_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));
|
||||
|
|
151
Oqtane.Client/Modules/Admin/Themes/Create.razor
Normal file
151
Oqtane.Client/Modules/Admin/Themes/Create.razor
Normal file
|
@ -0,0 +1,151 @@
|
|||
@namespace Oqtane.Modules.Admin.Themes
|
||||
@inherits ModuleBase
|
||||
@inject NavigationManager NavigationManager
|
||||
@inject IThemeService ThemeService
|
||||
@inject IModuleService ModuleService
|
||||
@inject IPageModuleService PageModuleService
|
||||
@inject ISystemService SystemService
|
||||
@inject ISettingService SettingService
|
||||
@inject IStringLocalizer<Index> Localizer
|
||||
@using System.Text.RegularExpressions
|
||||
@using System.IO;
|
||||
|
||||
@if (_systeminfo != null && _templates != null)
|
||||
{
|
||||
<table class="table table-borderless">
|
||||
<tr>
|
||||
<td>
|
||||
<Label For="owner" HelpText="Enter the name of the organization who is developing this theme. It should not contain spaces or punctuation." ResourceKey="OwnerName">Owner Name: </Label>
|
||||
</td>
|
||||
<td>
|
||||
<input id="owner" class="form-control" @bind="@_owner" />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<Label For="module" HelpText="Enter a name for this theme. It should not contain spaces or punctuation." ResourceKey="ThemeName">Theme Name: </Label>
|
||||
</td>
|
||||
<td>
|
||||
<input id="module" class="form-control" @bind="@_theme" />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<Label For="template" HelpText="Select a theme template. Templates are located in the wwwroot/Themes/Templates folder on the server." ResourceKey="Template">Template: </Label>
|
||||
</td>
|
||||
<td>
|
||||
<select id="template" class="form-control" @onchange="(e => TemplateChanged(e))">
|
||||
<option value="-"><@Localizer["Select Template"]></option>
|
||||
@foreach (string template in _templates)
|
||||
{
|
||||
<option value="@template">@template</option>
|
||||
}
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<Label For="reference" HelpText="Select a framework reference version" ResourceKey="FrameworkReference">Framework Reference: </Label>
|
||||
</td>
|
||||
<td>
|
||||
<select id="reference" class="form-control" @bind="@_reference">
|
||||
@foreach (string version in Constants.ReleaseVersions.Split(','))
|
||||
{
|
||||
if (Version.Parse(version).CompareTo(Version.Parse("2.0.0")) >= 0)
|
||||
{
|
||||
<option value="@(version)">@(version)</option>
|
||||
}
|
||||
}
|
||||
<option value="local">@Localizer["Local Version"]</option>
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
@if (!string.IsNullOrEmpty(_location))
|
||||
{
|
||||
<tr>
|
||||
<td>
|
||||
<Label For="location" HelpText="Location where the theme will be created" ResourceKey="Location">Location: </Label>
|
||||
</td>
|
||||
<td>
|
||||
<input id="module" class="form-control" @bind="@_location" readonly />
|
||||
</td>
|
||||
</tr>
|
||||
}
|
||||
</table>
|
||||
<button type="button" class="btn btn-success" @onclick="CreateTheme">@Localizer["Create Theme"]</button>
|
||||
<NavLink class="btn btn-secondary" href="@NavigateUrl()">@Localizer["Cancel"]</NavLink>
|
||||
}
|
||||
|
||||
@code {
|
||||
private string _owner = string.Empty;
|
||||
private string _theme = string.Empty;
|
||||
private string _template = "-";
|
||||
private string _reference = Constants.Version;
|
||||
private string _location = string.Empty;
|
||||
|
||||
private Dictionary<string, string> _systeminfo;
|
||||
private List<string> _templates;
|
||||
|
||||
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Host;
|
||||
|
||||
protected override async Task OnParametersSetAsync()
|
||||
{
|
||||
try
|
||||
{
|
||||
_systeminfo = await SystemService.GetSystemInfoAsync();
|
||||
_templates = await ThemeService.GetThemeTemplatesAsync();
|
||||
AddModuleMessage(Localizer["Please Note That The Theme Creator Is Only Intended To Be Used In A Development Environment"], MessageType.Info);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
await logger.LogError(ex, "Error Loading Theme Creator");
|
||||
}
|
||||
}
|
||||
|
||||
private async Task CreateTheme()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (IsValid(_owner) && IsValid(_theme) && _owner != _theme && _template != "-")
|
||||
{
|
||||
var theme = new Theme { Owner = _owner, Name = _theme, Template = _template, Version = _reference };
|
||||
theme = await ThemeService.CreateThemeAsync(theme);
|
||||
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 <a href=\"{0}\">Restart</a> Your Application To Activate The Module.", NavigateUrl("admin/system")], MessageType.Success);
|
||||
}
|
||||
else
|
||||
{
|
||||
AddModuleMessage(Localizer["You Must Provide A Valid Owner Name And Theme 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 Theme");
|
||||
}
|
||||
}
|
||||
|
||||
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 + "." + _theme;
|
||||
}
|
||||
StateHasChanged();
|
||||
}
|
||||
}
|
|
@ -13,6 +13,8 @@
|
|||
else
|
||||
{
|
||||
<ActionLink Action="Add" Text="Install Theme" />
|
||||
@((MarkupString)" ")
|
||||
<ActionLink Action="Create" Text="Create Theme" ResourceKey="CreateTheme" />
|
||||
|
||||
<Pager Items="@_themes">
|
||||
<Header>
|
||||
|
@ -26,17 +28,17 @@ else
|
|||
<td><ActionLink Action="View" Parameters="@($"name=" + WebUtility.UrlEncode(context.ThemeName))" ResourceKey="ViewTheme" /></td>
|
||||
<td>
|
||||
@if (context.AssemblyName != "Oqtane.Client")
|
||||
{
|
||||
{
|
||||
<ActionDialog Header="Delete Theme" Message="@Localizer["Are You Sure You Wish To Delete The {0} Theme?", context.Name]" Action="Delete" Security="SecurityAccessLevel.Host" Class="btn btn-danger" OnClick="@(async () => await DeleteTheme(context))" ResourceKey="DeleteTheme" />
|
||||
}
|
||||
}
|
||||
</td>
|
||||
<td>@context.Name</td>
|
||||
<td>@context.Version</td>
|
||||
<td>
|
||||
@if (UpgradeAvailable(context.ThemeName, context.Version))
|
||||
{
|
||||
{
|
||||
<button type="button" class="btn btn-success" @onclick=@(async () => await DownloadTheme(context.ThemeName, context.Version))>@Localizer["Upgrade"]</button>
|
||||
}
|
||||
}
|
||||
</td>
|
||||
<td></td>
|
||||
</Row>
|
||||
|
|
|
@ -6,21 +6,24 @@
|
|||
<div class="col">
|
||||
<TabStrip>
|
||||
<TabPanel Name="Rich" Heading="Rich Text Editor">
|
||||
@if (_filemanagervisible)
|
||||
@if (AllowFileManagement)
|
||||
{
|
||||
<FileManager @ref="_fileManager" Filter="@Constants.ImageFiles" />
|
||||
<ModuleMessage Message="@_message" Type="MessageType.Warning"></ModuleMessage>
|
||||
<br />
|
||||
}
|
||||
<div class="row justify-content-center" style="margin-bottom: 20px;">
|
||||
<button type="button" class="btn btn-secondary" @onclick="RefreshRichText">@Localizer["Synchronize Content"]</button>
|
||||
<button type="button" class="btn btn-primary" @onclick="InsertImage">@Localizer["Insert Image"]</button>
|
||||
@if (_filemanagervisible)
|
||||
{
|
||||
@((MarkupString)" ")
|
||||
<button type="button" class="btn btn-secondary" @onclick="CloseFileManager">@Localizer["Close"]</button>
|
||||
<FileManager @ref="_fileManager" Filter="@Constants.ImageFiles" />
|
||||
<ModuleMessage Message="@_message" Type="MessageType.Warning"></ModuleMessage>
|
||||
<br />
|
||||
}
|
||||
</div>
|
||||
<div class="row justify-content-center" style="margin-bottom: 20px;">
|
||||
<button type="button" class="btn btn-secondary" @onclick="RefreshRichText">@Localizer["Synchronize Content"]</button>
|
||||
<button type="button" class="btn btn-primary" @onclick="InsertImage">@Localizer["Insert Image"]</button>
|
||||
@if (_filemanagervisible)
|
||||
{
|
||||
@((MarkupString)" ")
|
||||
<button type="button" class="btn btn-secondary" @onclick="CloseFileManager">@Localizer["Close"]</button>
|
||||
}
|
||||
</div>
|
||||
}
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<div @ref="@_toolBar">
|
||||
|
@ -107,6 +110,9 @@
|
|||
[Parameter]
|
||||
public string DebugLevel { get; set; } = "info";
|
||||
|
||||
[Parameter]
|
||||
public bool AllowFileManagement { get; set; } = true;
|
||||
|
||||
public override List<Resource> Resources => new List<Resource>()
|
||||
{
|
||||
new Resource { ResourceType = ResourceType.Script, Bundle = "Quill", Url = "js/quill1.3.6.min.js" },
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
{
|
||||
@if (IsAuthorized(tabPanel))
|
||||
{
|
||||
<li class="nav-item">
|
||||
<li class="nav-item" @key="tabPanel.Name">
|
||||
@if (tabPanel.Name == ActiveTab)
|
||||
{
|
||||
<a class="nav-link active" data-toggle="tab" href="#@tabPanel.Name" role="tab" @onclick:preventDefault="true">
|
||||
|
@ -35,7 +35,7 @@
|
|||
</CascadingValue>
|
||||
|
||||
@code {
|
||||
private List<TabPanel> _tabPanels = new List<TabPanel>();
|
||||
private List<TabPanel> _tabPanels;
|
||||
|
||||
[Parameter]
|
||||
public RenderFragment ChildContent { get; set; } // contains the TabPanels
|
||||
|
@ -51,14 +51,22 @@
|
|||
}
|
||||
}
|
||||
|
||||
protected override void OnParametersSet()
|
||||
{
|
||||
_tabPanels = new List<TabPanel>();
|
||||
}
|
||||
|
||||
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)
|
||||
|
|
|
@ -4,12 +4,13 @@
|
|||
@namespace Oqtane.Modules.HtmlText
|
||||
@inherits ModuleBase
|
||||
@inject IHtmlTextService HtmlTextService
|
||||
@inject ISettingService SettingService
|
||||
@inject NavigationManager NavigationManager
|
||||
@inject IStringLocalizer<Edit> Localizer
|
||||
|
||||
@if (_content != null)
|
||||
{
|
||||
<RichTextEditor Content="@_content" @ref="@RichTextEditorHtml"></RichTextEditor>
|
||||
<RichTextEditor Content="@_content" AllowFileManagement="@_allowfilemanagement" @ref="@RichTextEditorHtml"></RichTextEditor>
|
||||
<button type="button" class="btn btn-success" @onclick="SaveContent">@Localizer["Save"]</button>
|
||||
<NavLink class="btn btn-secondary" href="@NavigateUrl()">@Localizer["Cancel"]</NavLink>
|
||||
@if (!string.IsNullOrEmpty(_content))
|
||||
|
@ -26,13 +27,14 @@
|
|||
public override string Title => "Edit Html/Text";
|
||||
|
||||
public override List<Resource> Resources => new List<Resource>()
|
||||
{
|
||||
{
|
||||
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)
|
||||
{
|
||||
|
|
|
@ -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"
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
49
Oqtane.Client/Modules/HtmlText/Settings.razor
Normal file
49
Oqtane.Client/Modules/HtmlText/Settings.razor
Normal file
|
@ -0,0 +1,49 @@
|
|||
@namespace Oqtane.Modules.HtmlText
|
||||
@inherits ModuleBase
|
||||
@inject ISettingService SettingService
|
||||
@implements Oqtane.Interfaces.ISettingsControl
|
||||
@inject IStringLocalizer<Settings> Localizer
|
||||
|
||||
<table class="table table-borderless">
|
||||
<tr>
|
||||
<td>
|
||||
<Label For="files" ResourceKey="Allow File Management" HelpText="Specify If Editors Can Upload and Select Files">Allow File Management: </Label>
|
||||
</td>
|
||||
<td>
|
||||
<select id="files" class="form-control" @bind="@_allowfilemanagement">
|
||||
<option value="true">@Localizer["Yes"]</option>
|
||||
<option value="false">@Localizer["No"]</option>
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
@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);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -5,7 +5,7 @@
|
|||
<OutputType>Exe</OutputType>
|
||||
<RazorLangVersion>3.0</RazorLangVersion>
|
||||
<Configurations>Debug;Release</Configurations>
|
||||
<Version>2.0.1</Version>
|
||||
<Version>2.0.2</Version>
|
||||
<Product>Oqtane</Product>
|
||||
<Authors>Shaun Walker</Authors>
|
||||
<Company>.NET Foundation</Company>
|
||||
|
@ -14,18 +14,11 @@
|
|||
<PackageProjectUrl>https://www.oqtane.org</PackageProjectUrl>
|
||||
<RepositoryUrl>https://github.com/oqtane</RepositoryUrl>
|
||||
<RepositoryType>Git</RepositoryType>
|
||||
<PackageReleaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v2.0.1</PackageReleaseNotes>
|
||||
<PackageReleaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v2.0.2</PackageReleaseNotes>
|
||||
<RootNamespace>Oqtane</RootNamespace>
|
||||
<IsPackable>true</IsPackable>
|
||||
<BlazorWebAssemblyLoadAllGlobalizationData>true</BlazorWebAssemblyLoadAllGlobalizationData>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Remove="Modules\Admin\ModuleCreator\Templates\**" />
|
||||
<Content Remove="Modules\Admin\ModuleCreator\Templates\**" />
|
||||
<EmbeddedResource Remove="Modules\Admin\ModuleCreator\Templates\**" />
|
||||
<None Remove="Modules\Admin\ModuleCreator\Templates\**" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="5.0.0" />
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -35,13 +35,7 @@ namespace Oqtane.Services
|
|||
|
||||
public async Task<Folder> GetFolderAsync(int siteId, [NotNull] string folderPath)
|
||||
{
|
||||
if (!(folderPath.EndsWith(System.IO.Path.DirectorySeparatorChar) || folderPath.EndsWith(System.IO.Path.AltDirectorySeparatorChar)))
|
||||
{
|
||||
folderPath = Utilities.PathCombine(folderPath, System.IO.Path.DirectorySeparatorChar.ToString());
|
||||
}
|
||||
|
||||
var path = WebUtility.UrlEncode(folderPath);
|
||||
|
||||
return await GetJsonAsync<Folder>($"{ApiUrl}/{siteId}/{path}");
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
using Oqtane.Models;
|
||||
using Oqtane.Models;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
|
@ -12,5 +12,7 @@ namespace Oqtane.Services
|
|||
List<ThemeControl> GetContainerControls(List<Theme> themes, string themeName);
|
||||
Task InstallThemesAsync();
|
||||
Task DeleteThemeAsync(string themeName);
|
||||
Task<Theme> CreateThemeAsync(Theme theme);
|
||||
Task<List<string>> GetThemeTemplatesAsync();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net.Http;
|
||||
using System.Threading.Tasks;
|
||||
|
@ -29,10 +29,10 @@ namespace Oqtane.Services
|
|||
return themes.SelectMany(item => item.Themes).ToList();
|
||||
}
|
||||
|
||||
//[Obsolete("This method is deprecated.", false)]
|
||||
public List<ThemeControl> GetLayoutControls(List<Theme> themes, string themeName)
|
||||
{
|
||||
return themes.Where(item => Utilities.GetTypeName(themeName).StartsWith(Utilities.GetTypeName(item.ThemeName)))
|
||||
.SelectMany(item => item.Layouts).ToList();
|
||||
return null;
|
||||
}
|
||||
|
||||
public List<ThemeControl> GetContainerControls(List<Theme> themes, string themeName)
|
||||
|
@ -50,5 +50,16 @@ namespace Oqtane.Services
|
|||
{
|
||||
await DeleteAsync($"{ApiUrl}/{themeName}");
|
||||
}
|
||||
|
||||
public async Task<Theme> CreateThemeAsync(Theme theme)
|
||||
{
|
||||
return await PostJsonAsync($"{ApiUrl}", theme);
|
||||
}
|
||||
|
||||
public async Task<List<string>> GetThemeTemplatesAsync()
|
||||
{
|
||||
List<string> templates = await GetJsonAsync<List<string>>($"{ApiUrl}/templates");
|
||||
return templates;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
@namespace Oqtane.Themes.BlazorTheme
|
||||
@namespace Oqtane.Themes.BlazorTheme
|
||||
@inherits ThemeBase
|
||||
|
||||
<div class="breadcrumbs">
|
||||
|
@ -17,16 +17,13 @@
|
|||
</div>
|
||||
<div class="container">
|
||||
<div class="row px-4">
|
||||
<Pane Name="Content" />
|
||||
</div>
|
||||
<div class="row px-4">
|
||||
<Pane Name="Admin" />
|
||||
<Pane Name="@PaneNames.Admin" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@code {
|
||||
public override string Panes => "Content";
|
||||
public override string Panes => PaneNames.Admin;
|
||||
|
||||
public override List<Resource> Resources => new List<Resource>()
|
||||
{
|
45
Oqtane.Client/Themes/Controls/Container/ModuleActions.razor
Normal file
45
Oqtane.Client/Themes/Controls/Container/ModuleActions.razor
Normal file
|
@ -0,0 +1,45 @@
|
|||
@namespace Oqtane.Themes.Controls
|
||||
@inherits ModuleActionsBase
|
||||
@attribute [OqtaneIgnore]
|
||||
|
||||
@if (PageState.EditMode && UserSecurity.IsAuthorized(PageState.User,PermissionNames.Edit, ModuleState.Permissions) && PageState.Action == Constants.DefaultAction)
|
||||
{
|
||||
<div class="app-moduleactions">
|
||||
<a class="nav-link dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false"></a>
|
||||
<ul class="dropdown-menu" x-placement="bottom-start" style="position: absolute; will-change: transform; top: 0px; left: 0px; transform: translate3d(0px, 37px, 0px);">
|
||||
@foreach (var action in Actions.Where(item => !item.Name.Contains("Pane")))
|
||||
{
|
||||
if (string.IsNullOrEmpty(action.Name))
|
||||
{
|
||||
<li class="dropdown-divider"></li>
|
||||
}
|
||||
else
|
||||
{
|
||||
<li>
|
||||
<a class="dropdown-item" @onclick="(async () => await ModuleAction(action))">
|
||||
<span class="@action.Icon" aria-hidden="true"></span> @action.Name
|
||||
</a>
|
||||
</li>
|
||||
}
|
||||
}
|
||||
@if (Actions.Where(item => item.Name.Contains("Pane")).Any())
|
||||
{
|
||||
<li class="dropdown-submenu">
|
||||
<a class="dropdown-item" onclick="return subMenu(this)">
|
||||
<span class="@Icons.AccountLogin" aria-hidden="true"></span> Move To >
|
||||
</a>
|
||||
<ul class="dropdown-menu">
|
||||
@foreach (var action in Actions.Where(item => item.Name.Contains("Pane")))
|
||||
{
|
||||
<li>
|
||||
<a class="dropdown-item" @onclick="(async () => await ModuleAction(action))">
|
||||
<span class="@action.Icon" aria-hidden="true"></span> @action.Name
|
||||
</a>
|
||||
</li>
|
||||
}
|
||||
</ul>
|
||||
</li>
|
||||
}
|
||||
</ul>
|
||||
</div>
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
@ -76,7 +76,7 @@ namespace Oqtane.Themes.Controls
|
|||
{
|
||||
if (pane != ModuleState.Pane)
|
||||
{
|
||||
actionList.Add(new ActionViewModel {Icon = Icons.AccountLogin, Name = "Move To " + pane + " Pane", Action = async (s, m) => await MoveToPane(s, pane, m)});
|
||||
actionList.Add(new ActionViewModel {Icon = Icons.AccountLogin, Name = pane + " Pane", Action = async (s, m) => await MoveToPane(s, pane, m)});
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,12 +0,0 @@
|
|||
@namespace Oqtane.Themes.Controls
|
||||
@inherits ThemeControlBase
|
||||
|
||||
@if (!string.IsNullOrWhiteSpace(Value))
|
||||
{
|
||||
<span class="@Value" aria-hidden="true"></span>
|
||||
}
|
||||
|
||||
@code {
|
||||
[Parameter()]
|
||||
public string Value { get; set; }
|
||||
}
|
|
@ -1,34 +0,0 @@
|
|||
@namespace Oqtane.Themes.Controls
|
||||
@inherits ModuleActionsBase
|
||||
@attribute [OqtaneIgnore]
|
||||
|
||||
@if (PageState.EditMode && UserSecurity.IsAuthorized(PageState.User,PermissionNames.Edit, ModuleState.Permissions))
|
||||
{
|
||||
<div class="app-moduleactions">
|
||||
<a class="nav-link dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false"></a>
|
||||
<div class="dropdown-menu" x-placement="bottom-start" style="position: absolute; will-change: transform; top: 0px; left: 0px; transform: translate3d(0px, 37px, 0px);">
|
||||
@foreach (var action in Actions)
|
||||
{
|
||||
if (string.IsNullOrEmpty(action.Name))
|
||||
{
|
||||
<div class="dropdown-divider"></div>
|
||||
}
|
||||
else
|
||||
{
|
||||
<a class="dropdown-item" @onclick="(async () => await ModuleAction(action))">
|
||||
@if (string.IsNullOrEmpty(action.Icon))
|
||||
{
|
||||
@((MarkupString) " ");
|
||||
}
|
||||
else
|
||||
{
|
||||
<span class="@action.Icon" aria-hidden="true"></span>
|
||||
}
|
||||
|
||||
@action.Name
|
||||
</a>
|
||||
}
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
}
|
|
@ -599,7 +599,7 @@
|
|||
Dictionary<string, string> 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()
|
|
@ -3,17 +3,19 @@ using System.Threading.Tasks;
|
|||
using Microsoft.AspNetCore.Components;
|
||||
using Microsoft.JSInterop;
|
||||
using Oqtane.Providers;
|
||||
using Oqtane.Security;
|
||||
using Oqtane.Services;
|
||||
using Oqtane.Shared;
|
||||
using Oqtane.UI;
|
||||
|
||||
namespace Oqtane.Themes.Controls
|
||||
{
|
||||
public class LoginBase : ThemeControlBase
|
||||
{
|
||||
[Inject] public NavigationManager NavigationManager {get;set;}
|
||||
[Inject]public IUserService UserService {get;set;}
|
||||
[Inject]public IJSRuntime jsRuntime {get;set;}
|
||||
[Inject]public IServiceProvider ServiceProvider {get;set;}
|
||||
[Inject] public NavigationManager NavigationManager { get; set; }
|
||||
[Inject] public IUserService UserService { get; set; }
|
||||
[Inject] public IJSRuntime jsRuntime { get; set; }
|
||||
[Inject] public IServiceProvider ServiceProvider { get; set; }
|
||||
|
||||
protected void LoginUser()
|
||||
{
|
||||
|
@ -29,13 +31,14 @@ namespace Oqtane.Themes.Controls
|
|||
{
|
||||
await UserService.LogoutUserAsync(PageState.User);
|
||||
PageState.User = null;
|
||||
bool authorizedtoviewpage = UserSecurity.IsAuthorized(PageState.User, PermissionNames.View, PageState.Page.Permissions);
|
||||
|
||||
if (PageState.Runtime == Oqtane.Shared.Runtime.Server)
|
||||
{
|
||||
// server-side Blazor
|
||||
var interop = new Interop(jsRuntime);
|
||||
string antiforgerytoken = await interop.GetElementByName("__RequestVerificationToken");
|
||||
var fields = new { __RequestVerificationToken = antiforgerytoken, returnurl = (PageState.Alias.Path + "/" + PageState.Page.Path) };
|
||||
var fields = new { __RequestVerificationToken = antiforgerytoken, returnurl = !authorizedtoviewpage ? PageState.Alias.Path : PageState.Alias.Path + "/" + PageState.Page.Path };
|
||||
await interop.SubmitForm($"/{PageState.Alias.AliasId}/pages/logout/", fields);
|
||||
}
|
||||
else
|
||||
|
@ -43,7 +46,7 @@ namespace Oqtane.Themes.Controls
|
|||
// client-side Blazor
|
||||
var authstateprovider = (IdentityAuthenticationStateProvider)ServiceProvider.GetService(typeof(IdentityAuthenticationStateProvider));
|
||||
authstateprovider.NotifyAuthenticationChanged();
|
||||
NavigationManager.NavigateTo(NavigateUrl(PageState.Page.Path, "reload"));
|
||||
NavigationManager.NavigateTo(NavigateUrl(!authorizedtoviewpage ? PageState.Alias.Path : PageState.Page.Path, "reload"));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
namespace Oqtane.Themes
|
||||
namespace Oqtane.Themes
|
||||
{
|
||||
public interface ILayoutControl
|
||||
{
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
namespace Oqtane.Themes
|
||||
using System;
|
||||
|
||||
namespace Oqtane.Themes
|
||||
{
|
||||
[Obsolete("This class is deprecated", false)]
|
||||
public abstract class LayoutBase : ThemeBase, ILayoutControl
|
||||
{
|
||||
|
||||
|
|
47
Oqtane.Client/Themes/OqtaneTheme/Containers/Container.razor
Normal file
47
Oqtane.Client/Themes/OqtaneTheme/Containers/Container.razor
Normal file
|
@ -0,0 +1,47 @@
|
|||
@namespace Oqtane.Themes.OqtaneTheme
|
||||
@inherits ContainerBase
|
||||
@inject ISettingService SettingService
|
||||
|
||||
<div class="@_classes">
|
||||
@if (_title)
|
||||
{
|
||||
<div class="row px-4">
|
||||
<div class="d-flex flex-nowrap">
|
||||
<ModuleActions /><h2><ModuleTitle /></h2>
|
||||
</div>
|
||||
<hr class="app-rule" />
|
||||
</div>
|
||||
}
|
||||
else
|
||||
{
|
||||
<ModuleActions />
|
||||
}
|
||||
<div class="row px-4">
|
||||
<div class="container">
|
||||
<ModuleInstance />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@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
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,113 @@
|
|||
@namespace Oqtane.Themes.OqtaneTheme
|
||||
@inherits ModuleBase
|
||||
@implements Oqtane.Interfaces.ISettingsControl
|
||||
@inject ISettingService SettingService
|
||||
@attribute [OqtaneIgnore]
|
||||
|
||||
<table class="table table-borderless">
|
||||
<tr>
|
||||
<td>
|
||||
<Label For="title" ResourceKey="Title" HelpText="Specify If The Module Title Should Be Displayed">Display Title?</Label>
|
||||
</td>
|
||||
<td>
|
||||
<select id="title" class="form-control" @bind="@_title">
|
||||
<option value="true">Yes</option>
|
||||
<option value="false">No</option>
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<Label For="background\" ResourceKey="Background" HelpText="Optionally Specify A Background Color For The Container">Background Color:</Label>
|
||||
</td>
|
||||
<td>
|
||||
<select id="background" class="form-control" @bind="@_background">
|
||||
<option value="">None</option>
|
||||
<option value="bg-primary">Primary</option>
|
||||
<option value="bg-secondary">Secondary</option>
|
||||
<option value="bg-success">Success</option>
|
||||
<option value="bg-danger">Danger</option>
|
||||
<option value="bg-warning">Warning</option>
|
||||
<option value="bg-info">Info</option>
|
||||
<option value="bg-light">Light</option>
|
||||
<option value="bg-dark">Dark</option>
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<Label For="text" ResourceKey="Text" HelpText="Optionally Specify A Text Color For The Container">Text Color:</Label>
|
||||
</td>
|
||||
<td>
|
||||
<select id="text" class="form-control" @bind="@_text">
|
||||
<option value="">None</option>
|
||||
<option value="text-primary">Primary</option>
|
||||
<option value="text-secondary">Secondary</option>
|
||||
<option value="text-success">Success</option>
|
||||
<option value="text-danger">Danger</option>
|
||||
<option value="text-warning">Warning</option>
|
||||
<option value="text-info">Info</option>
|
||||
<option value="text-light">Light</option>
|
||||
<option value="text-dark">Dark</option>
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<Label For="border" ResourceKey="Border" HelpText="Optionally Specify A Border For The Container">Border Color:</Label>
|
||||
</td>
|
||||
<td>
|
||||
<select id="border" class="form-control" @bind="@_border">
|
||||
<option value="">None</option>
|
||||
<option value="border">Default</option>
|
||||
<option value="border border-primary">Primary</option>
|
||||
<option value="border border-secondary">Secondary</option>
|
||||
<option value="border border-success">Success</option>
|
||||
<option value="border border-danger">Danger</option>
|
||||
<option value="border border-warning">Warning</option>
|
||||
<option value="border border-info">Info</option>
|
||||
<option value="border border-light">Light</option>
|
||||
<option value="border border-dark">Dark</option>
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
@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);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,32 +0,0 @@
|
|||
@namespace Oqtane.Themes.OqtaneTheme
|
||||
@inherits ThemeBase
|
||||
|
||||
<main role="main">
|
||||
<nav class="navbar navbar-expand-md navbar-dark bg-primary fixed-top">
|
||||
<Logo /><Menu Orientation="Horizontal" />
|
||||
<div class="controls ml-md-auto">
|
||||
<div class="controls-group"><UserProfile /> <Login /> <ControlPanel /></div>
|
||||
</div>
|
||||
</nav>
|
||||
<div class="content container">
|
||||
<PaneLayout />
|
||||
<div class="row px-4">
|
||||
<Pane Name="Admin" />
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
@code {
|
||||
public override string Name => "Default";
|
||||
|
||||
public override string Panes => string.Empty;
|
||||
|
||||
public override List<Resource> Resources => new List<Resource>()
|
||||
{
|
||||
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" }
|
||||
};
|
||||
}
|
|
@ -1,20 +0,0 @@
|
|||
@namespace Oqtane.Themes.OqtaneTheme
|
||||
@inherits LayoutBase
|
||||
|
||||
<div class="row px-4">
|
||||
<Pane Name="Top" />
|
||||
</div>
|
||||
<div class="row px-4">
|
||||
<div class="col-sm"><Pane Name="Left" /></div>
|
||||
<div class="col-sm"><Pane Name="Content" /></div>
|
||||
<div class="col-sm"><Pane Name="Right" /></div>
|
||||
</div>
|
||||
<div class="row px-4">
|
||||
<Pane Name="Bottom" />
|
||||
</div>
|
||||
|
||||
@code {
|
||||
public override string Name => "Multiple Panes";
|
||||
|
||||
public override string Panes => "Top,Left,Content,Right,Bottom";
|
||||
}
|
|
@ -1,13 +0,0 @@
|
|||
@namespace Oqtane.Themes.OqtaneTheme
|
||||
@inherits ContainerBase
|
||||
<div class="container">
|
||||
@if (PageState.EditMode)
|
||||
{
|
||||
<ModuleActions />
|
||||
}
|
||||
<ModuleInstance />
|
||||
</div>
|
||||
|
||||
@code {
|
||||
public override string Name => "No Header";
|
||||
}
|
|
@ -1,12 +0,0 @@
|
|||
@namespace Oqtane.Themes.OqtaneTheme
|
||||
@inherits LayoutBase
|
||||
|
||||
<div class="row px-4">
|
||||
<Pane Name="Content" />
|
||||
</div>
|
||||
|
||||
@code {
|
||||
public override string Name => "Single Pane";
|
||||
|
||||
public override string Panes => "Content";
|
||||
}
|
|
@ -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"
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
131
Oqtane.Client/Themes/OqtaneTheme/Themes/Default.razor
Normal file
131
Oqtane.Client/Themes/OqtaneTheme/Themes/Default.razor
Normal file
|
@ -0,0 +1,131 @@
|
|||
@namespace Oqtane.Themes.OqtaneTheme
|
||||
@inherits ThemeBase
|
||||
@inject ISettingService SettingService
|
||||
|
||||
<main role="main">
|
||||
<nav class="navbar navbar-expand-md navbar-dark bg-primary fixed-top">
|
||||
<Logo /><Menu Orientation="Horizontal" />
|
||||
<div class="controls ml-md-auto">
|
||||
<div class="controls-group"><UserProfile /> <Login /> <ControlPanel /></div>
|
||||
</div>
|
||||
</nav>
|
||||
<div class="content">
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<Pane Name="@PaneNames.Admin" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<Pane Name="Top Full Width" />
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<Pane Name="Top 100%" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<Pane Name="Left 50%" />
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<Pane Name="Right 50%" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-4">
|
||||
<Pane Name="Left 33%" />
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<Pane Name="Center 33%" />
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<Pane Name="Right 33%" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-3">
|
||||
<Pane Name="Left Outer 25%" />
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<Pane Name="Left Inner 25%" />
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<Pane Name="Right Inner 25%" />
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<Pane Name="Right Outer 25%" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-3">
|
||||
<Pane Name="Left 25%" />
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<Pane Name="Center 50%" />
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<Pane Name="Right 25%" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-8">
|
||||
<Pane Name="Left Sidebar 66%" />
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<Pane Name="Right Sidebar 33%" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-4">
|
||||
<Pane Name="Left Sidebar 33%" />
|
||||
</div>
|
||||
<div class="col-md-8">
|
||||
<Pane Name="Right Sidebar 66%" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<Pane Name="Bottom 100%" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<Pane Name="Bottom Full Width" />
|
||||
@if (_footer)
|
||||
{
|
||||
<div class="bg-primary footer">
|
||||
<Pane Name="Footer" />
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
</main>
|
||||
|
||||
@code {
|
||||
public override string Name => "Default Theme";
|
||||
|
||||
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<Resource> Resources => new List<Resource>()
|
||||
{
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
}
|
49
Oqtane.Client/Themes/OqtaneTheme/Themes/ThemeSettings.razor
Normal file
49
Oqtane.Client/Themes/OqtaneTheme/Themes/ThemeSettings.razor
Normal file
|
@ -0,0 +1,49 @@
|
|||
@namespace Oqtane.Themes.OqtaneTheme
|
||||
@inherits ModuleBase
|
||||
@implements Oqtane.Interfaces.ISettingsControl
|
||||
@inject ISettingService SettingService
|
||||
@attribute [OqtaneIgnore]
|
||||
|
||||
<table class="table table-borderless">
|
||||
<tr>
|
||||
<td>
|
||||
<Label For="title" ResourceKey="Title" HelpText="Specify If The Page Footer Should Be Displayed">Display Footer?</Label>
|
||||
</td>
|
||||
<td>
|
||||
<select id="title" class="form-control" @bind="@_footer">
|
||||
<option value="true">Yes</option>
|
||||
<option value="false">No</option>
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
@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);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,29 +1,46 @@
|
|||
@namespace Oqtane.UI
|
||||
|
||||
<CascadingValue Value="@_moduleState" IsFixed="true">
|
||||
@DynamicComponent
|
||||
<CascadingValue Value="@ModuleState" IsFixed="true">
|
||||
@if (_useadminborder)
|
||||
{
|
||||
<div class="app-pane-admin-border">
|
||||
@DynamicComponent
|
||||
</div>
|
||||
}
|
||||
else
|
||||
{
|
||||
@DynamicComponent
|
||||
}
|
||||
</CascadingValue>
|
||||
|
||||
@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;
|
||||
}
|
||||
|
||||
if (PageState.EditMode && UserSecurity.IsAuthorized(PageState.User, PermissionNames.Edit, PageState.Page.Permissions) && PageState.Action == Constants.DefaultAction)
|
||||
{
|
||||
_useadminborder = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
_useadminborder = false;
|
||||
}
|
||||
|
||||
DynamicComponent = builder =>
|
||||
{
|
||||
Type containerType = Type.GetType(container);
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
using Microsoft.AspNetCore.Components;
|
||||
using Microsoft.JSInterop;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
|
@ -232,5 +233,19 @@ namespace Oqtane.UI
|
|||
return Task.CompletedTask;
|
||||
}
|
||||
}
|
||||
|
||||
public ValueTask<bool> FormValid(ElementReference form)
|
||||
{
|
||||
try
|
||||
{
|
||||
return _jsRuntime.InvokeAsync<bool>(
|
||||
"Oqtane.Interop.formValid",
|
||||
form);
|
||||
}
|
||||
catch
|
||||
{
|
||||
return new ValueTask<bool>(Task.FromResult(false));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
@if (_useadminborder)
|
||||
{
|
||||
<div class="@_paneadminborder">
|
||||
<div class="app-pane-admin-border">
|
||||
@((MarkupString)_panetitle)
|
||||
@DynamicComponent
|
||||
</div>
|
||||
|
@ -18,7 +18,6 @@ else
|
|||
|
||||
@code {
|
||||
private bool _useadminborder = false;
|
||||
private string _paneadminborder = "app-pane-admin-border";
|
||||
private string _panetitle = "";
|
||||
|
||||
[CascadingParameter]
|
||||
|
@ -31,7 +30,7 @@ else
|
|||
|
||||
protected override void OnParametersSet()
|
||||
{
|
||||
if (PageState.EditMode && UserSecurity.IsAuthorized(PageState.User, PermissionNames.Edit, PageState.Page.Permissions) && Name != PaneNames.Admin)
|
||||
if (PageState.EditMode && UserSecurity.IsAuthorized(PageState.User, PermissionNames.Edit, PageState.Page.Permissions) && PageState.Action == Constants.DefaultAction)
|
||||
{
|
||||
_useadminborder = true;
|
||||
_panetitle = "<div class=\"app-pane-admin-title\">" + Name + " Pane</div>";
|
||||
|
@ -125,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();
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
|
@ -384,21 +384,15 @@
|
|||
page.ThemeType = site.DefaultThemeType;
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(page.LayoutType))
|
||||
{
|
||||
page.LayoutType = site.DefaultLayoutType;
|
||||
}
|
||||
|
||||
page.Panes = new List<string>();
|
||||
page.Resources = new List<Resource>();
|
||||
|
||||
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
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
|
||||
<metadata>
|
||||
<id>Oqtane.Client</id>
|
||||
<version>2.0.1</version>
|
||||
<version>2.0.2</version>
|
||||
<authors>Shaun Walker</authors>
|
||||
<owners>.NET Foundation</owners>
|
||||
<title>Oqtane Framework</title>
|
||||
|
@ -13,7 +13,7 @@
|
|||
<projectUrl>https://github.com/oqtane/oqtane.framework</projectUrl>
|
||||
<iconUrl>https://www.oqtane.org/Portals/0/icon.jpg</iconUrl>
|
||||
<tags>oqtane</tags>
|
||||
<releaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v2.0.1</releaseNotes>
|
||||
<releaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v2.0.2</releaseNotes>
|
||||
<summary>A modular application framework for Blazor</summary>
|
||||
</metadata>
|
||||
<files>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
|
||||
<metadata>
|
||||
<id>Oqtane.Framework</id>
|
||||
<version>2.0.1</version>
|
||||
<version>2.0.2</version>
|
||||
<authors>Shaun Walker</authors>
|
||||
<owners>.NET Foundation</owners>
|
||||
<title>Oqtane Framework</title>
|
||||
|
@ -13,7 +13,7 @@
|
|||
<projectUrl>https://github.com/oqtane/oqtane.framework</projectUrl>
|
||||
<iconUrl>https://www.oqtane.org/Portals/0/icon.jpg</iconUrl>
|
||||
<tags>oqtane framework</tags>
|
||||
<releaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v2.0.1</releaseNotes>
|
||||
<releaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v2.0.2</releaseNotes>
|
||||
<summary>A modular application framework for Blazor</summary>
|
||||
</metadata>
|
||||
<files>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
|
||||
<metadata>
|
||||
<id>Oqtane.Server</id>
|
||||
<version>2.0.1</version>
|
||||
<version>2.0.2</version>
|
||||
<authors>Shaun Walker</authors>
|
||||
<owners>.NET Foundation</owners>
|
||||
<title>Oqtane Framework</title>
|
||||
|
@ -13,7 +13,7 @@
|
|||
<projectUrl>https://github.com/oqtane/oqtane.framework</projectUrl>
|
||||
<iconUrl>https://www.oqtane.org/Portals/0/icon.jpg</iconUrl>
|
||||
<tags>oqtane</tags>
|
||||
<releaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v2.0.1</releaseNotes>
|
||||
<releaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v2.0.2</releaseNotes>
|
||||
<summary>A modular application framework for Blazor</summary>
|
||||
</metadata>
|
||||
<files>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
|
||||
<metadata>
|
||||
<id>Oqtane.Shared</id>
|
||||
<version>2.0.1</version>
|
||||
<version>2.0.2</version>
|
||||
<authors>Shaun Walker</authors>
|
||||
<owners>.NET Foundation</owners>
|
||||
<title>Oqtane Framework</title>
|
||||
|
@ -13,7 +13,7 @@
|
|||
<projectUrl>https://github.com/oqtane/oqtane.framework</projectUrl>
|
||||
<iconUrl>https://www.oqtane.org/Portals/0/icon.jpg</iconUrl>
|
||||
<tags>oqtane</tags>
|
||||
<releaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v2.0.1</releaseNotes>
|
||||
<releaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v2.0.2</releaseNotes>
|
||||
<summary>A modular application framework for Blazor</summary>
|
||||
</metadata>
|
||||
<files>
|
||||
|
|
|
@ -1 +1 @@
|
|||
Compress-Archive -Path "..\Oqtane.Server\bin\Release\net5.0\publish\*" -DestinationPath "..\Oqtane.Server\bin\Release\Oqtane.Framework.2.0.1.Install.zip" -Force
|
||||
Compress-Archive -Path "..\Oqtane.Server\bin\Release\net5.0\publish\*" -DestinationPath "..\Oqtane.Server\bin\Release\Oqtane.Framework.2.0.2.Install.zip" -Force
|
|
@ -1 +1 @@
|
|||
Compress-Archive -Path "..\Oqtane.Server\bin\Release\net5.0\publish\*" -DestinationPath "..\Oqtane.Server\bin\Release\Oqtane.Framework.2.0.1.Upgrade.zip" -Force
|
||||
Compress-Archive -Path "..\Oqtane.Server\bin\Release\net5.0\publish\*" -DestinationPath "..\Oqtane.Server\bin\Release\Oqtane.Framework.2.0.2.Upgrade.zip" -Force
|
|
@ -1,4 +1,4 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
|
@ -69,6 +69,10 @@ namespace Oqtane.Controllers
|
|||
public Folder GetByPath(int siteId, string path)
|
||||
{
|
||||
var folderPath = WebUtility.UrlDecode(path);
|
||||
if (!(folderPath.EndsWith(System.IO.Path.DirectorySeparatorChar) || folderPath.EndsWith(System.IO.Path.AltDirectorySeparatorChar)))
|
||||
{
|
||||
folderPath = Utilities.PathCombine(folderPath, System.IO.Path.DirectorySeparatorChar.ToString());
|
||||
}
|
||||
Folder folder = _folders.GetFolder(siteId, folderPath);
|
||||
if (folder != null)
|
||||
if (_userPermissions.IsAuthorized(User, PermissionNames.Browse, folder.Permissions))
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
});
|
||||
|
|
|
@ -175,9 +175,9 @@ namespace Oqtane.Controllers
|
|||
// GET: api/<controller>/templates
|
||||
[HttpGet("templates")]
|
||||
[Authorize(Roles = RoleNames.Host)]
|
||||
public List<string> Get()
|
||||
public List<string> GetTemplates()
|
||||
{
|
||||
var templates = new List<String>();
|
||||
var templates = new List<string>();
|
||||
string templatePath = Utilities.PathCombine(_environment.WebRootPath, "Modules", "Templates", Path.DirectorySeparatorChar.ToString());
|
||||
foreach (string directory in Directory.GetDirectories(templatePath))
|
||||
{
|
||||
|
@ -186,7 +186,7 @@ namespace Oqtane.Controllers
|
|||
return templates;
|
||||
}
|
||||
|
||||
// POST api/<controller>?moduleid=x
|
||||
// POST api/<controller>
|
||||
[HttpPost]
|
||||
[Authorize(Roles = RoleNames.Host)]
|
||||
public ModuleDefinition Post([FromBody] ModuleDefinition moduleDefinition)
|
||||
|
|
|
@ -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<Page> Get(string siteid)
|
||||
{
|
||||
List<Setting> settings = _settings.GetSettings(EntityNames.Page).ToList();
|
||||
|
||||
List<Page> pages = new List<Page>();
|
||||
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<Permission> {
|
||||
|
|
|
@ -103,5 +103,91 @@ namespace Oqtane.Controllers
|
|||
}
|
||||
}
|
||||
|
||||
// GET: api/<controller>/templates
|
||||
[HttpGet("templates")]
|
||||
[Authorize(Roles = RoleNames.Host)]
|
||||
public List<string> GetTemplates()
|
||||
{
|
||||
var templates = new List<string>();
|
||||
string templatePath = Utilities.PathCombine(_environment.WebRootPath, "Themes", "Templates", Path.DirectorySeparatorChar.ToString());
|
||||
foreach (string directory in Directory.GetDirectories(templatePath))
|
||||
{
|
||||
templates.Add(directory.Replace(templatePath, ""));
|
||||
}
|
||||
return templates;
|
||||
}
|
||||
|
||||
// POST api/<controller>
|
||||
[HttpPost]
|
||||
[Authorize(Roles = RoleNames.Host)]
|
||||
public Theme Post([FromBody] Theme theme)
|
||||
{
|
||||
if (ModelState.IsValid)
|
||||
{
|
||||
string rootPath;
|
||||
DirectoryInfo rootFolder = Directory.GetParent(_environment.ContentRootPath);
|
||||
string templatePath = Utilities.PathCombine(_environment.WebRootPath, "Themes", "Templates", theme.Template, Path.DirectorySeparatorChar.ToString());
|
||||
|
||||
rootPath = Utilities.PathCombine(rootFolder.Parent.FullName, theme.Owner + "." + theme.Name, Path.DirectorySeparatorChar.ToString());
|
||||
theme.ThemeName = theme.Owner + "." + theme.Name + ", " + theme.Owner + "." + theme.Name + ".Client.Oqtane";
|
||||
|
||||
ProcessTemplatesRecursively(new DirectoryInfo(templatePath), rootPath, rootFolder.Name, templatePath, theme);
|
||||
_logger.Log(LogLevel.Information, this, LogFunction.Create, "Theme Created {Theme}", theme);
|
||||
}
|
||||
|
||||
return theme;
|
||||
}
|
||||
|
||||
private void ProcessTemplatesRecursively(DirectoryInfo current, string rootPath, string rootFolder, string templatePath, Theme theme)
|
||||
{
|
||||
// process folder
|
||||
string folderPath = Utilities.PathCombine(rootPath, current.FullName.Replace(templatePath, ""));
|
||||
folderPath = folderPath.Replace("[Owner]", theme.Owner);
|
||||
folderPath = folderPath.Replace("[Theme]", theme.Name);
|
||||
if (!Directory.Exists(folderPath))
|
||||
{
|
||||
Directory.CreateDirectory(folderPath);
|
||||
}
|
||||
|
||||
FileInfo[] files = current.GetFiles("*.*");
|
||||
if (files != null)
|
||||
{
|
||||
foreach (FileInfo file in files)
|
||||
{
|
||||
// process file
|
||||
string filePath = Path.Combine(folderPath, file.Name);
|
||||
filePath = filePath.Replace("[Owner]", theme.Owner);
|
||||
filePath = filePath.Replace("[Theme]", theme.Name);
|
||||
|
||||
string text = System.IO.File.ReadAllText(file.FullName);
|
||||
text = text.Replace("[Owner]", theme.Owner);
|
||||
text = text.Replace("[Theme]", theme.Name);
|
||||
text = text.Replace("[RootPath]", rootPath);
|
||||
text = text.Replace("[RootFolder]", rootFolder);
|
||||
text = text.Replace("[Folder]", folderPath);
|
||||
text = text.Replace("[File]", Path.GetFileName(filePath));
|
||||
if (theme.Version == "local")
|
||||
{
|
||||
text = text.Replace("[FrameworkVersion]", Constants.Version);
|
||||
text = text.Replace("[ClientReference]", "<Reference Include=\"Oqtane.Client\"><HintPath>..\\..\\oqtane.framework\\Oqtane.Server\\bin\\Debug\\net5.0\\Oqtane.Client.dll</HintPath></Reference>");
|
||||
text = text.Replace("[SharedReference]", "<Reference Include=\"Oqtane.Shared\"><HintPath>..\\..\\oqtane.framework\\Oqtane.Server\\bin\\Debug\\net5.0\\Oqtane.Shared.dll</HintPath></Reference>");
|
||||
}
|
||||
else
|
||||
{
|
||||
text = text.Replace("[FrameworkVersion]", theme.Version);
|
||||
text = text.Replace("[ClientReference]", "<PackageReference Include=\"Oqtane.Client\" Version=\"" + theme.Version + "\" />");
|
||||
text = text.Replace("[SharedReference]", "<PackageReference Include=\"Oqtane.Shared\" Version=\"" + theme.Version + "\" />");
|
||||
}
|
||||
System.IO.File.WriteAllText(filePath, text);
|
||||
}
|
||||
|
||||
DirectoryInfo[] folders = current.GetDirectories();
|
||||
|
||||
foreach (DirectoryInfo folder in folders.Reverse())
|
||||
{
|
||||
ProcessTemplatesRecursively(folder, rootPath, rootFolder, templatePath, theme);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
};
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
namespace Oqtane.Infrastructure
|
||||
namespace Oqtane.Infrastructure
|
||||
{
|
||||
public interface ILocalizationManager
|
||||
{
|
||||
|
|
|
@ -1,9 +1,7 @@
|
|||
namespace Oqtane.Infrastructure
|
||||
namespace Oqtane.Infrastructure
|
||||
{
|
||||
public class LocalizationOptions
|
||||
{
|
||||
public string DefaultCulture { get; set; }
|
||||
|
||||
public string[] SupportedCultures { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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,20 @@ namespace Oqtane.Infrastructure
|
|||
: _localizationOptions.DefaultCulture;
|
||||
|
||||
public string[] GetSupportedCultures()
|
||||
=> _localizationOptions.SupportedCultures.IsNullOrEmpty()
|
||||
? SupportedCultures
|
||||
: _localizationOptions.SupportedCultures;
|
||||
{
|
||||
List<string> cultures = new List<string>();
|
||||
foreach(var file in Directory.EnumerateFiles(Path.GetDirectoryName(Assembly.GetEntryAssembly().Location), "Oqtane.Client.resources.dll", SearchOption.AllDirectories))
|
||||
{
|
||||
cultures.Add(Path.GetFileName(Path.GetDirectoryName(file)));
|
||||
}
|
||||
if (cultures.Count == 0)
|
||||
{
|
||||
return SupportedCultures;
|
||||
}
|
||||
else
|
||||
{
|
||||
return cultures.ToArray();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -48,7 +48,7 @@ namespace Oqtane.SiteTemplates
|
|||
new Permission(PermissionNames.Edit, RoleNames.Admin, true)
|
||||
}.EncodePermissions() ,
|
||||
PageTemplateModules = new List<PageTemplateModule> {
|
||||
new PageTemplateModule { ModuleDefinitionName = "Oqtane.Modules.HtmlText, Oqtane.Client", Title = "Welcome To Oqtane...", Pane = "Content",
|
||||
new PageTemplateModule { ModuleDefinitionName = "Oqtane.Modules.HtmlText, Oqtane.Client", Title = "Welcome To Oqtane...", Pane = PaneNames.Admin,
|
||||
ModulePermissions = new List<Permission> {
|
||||
new Permission(PermissionNames.View, RoleNames.Everyone, true),
|
||||
new Permission(PermissionNames.View, RoleNames.Admin, true),
|
||||
|
@ -70,7 +70,7 @@ namespace Oqtane.SiteTemplates
|
|||
"<p>The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.</p>" +
|
||||
"<p>THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.</p>"
|
||||
},
|
||||
new PageTemplateModule { ModuleDefinitionName = "Oqtane.Modules.HtmlText, Oqtane.Client", Title = "Secure Content", Pane = "Content",
|
||||
new PageTemplateModule { ModuleDefinitionName = "Oqtane.Modules.HtmlText, Oqtane.Client", Title = "Secure Content", Pane = PaneNames.Admin,
|
||||
ModulePermissions = new List<Permission> {
|
||||
new Permission(PermissionNames.View, RoleNames.Registered, true),
|
||||
new Permission(PermissionNames.View, RoleNames.Admin, true),
|
||||
|
@ -94,7 +94,7 @@ namespace Oqtane.SiteTemplates
|
|||
new Permission(PermissionNames.Edit, RoleNames.Admin, true)
|
||||
}.EncodePermissions(),
|
||||
PageTemplateModules = new List<PageTemplateModule> {
|
||||
new PageTemplateModule { ModuleDefinitionName = "Oqtane.Modules.HtmlText, Oqtane.Client", Title = "Secure Content", Pane = "Content",
|
||||
new PageTemplateModule { ModuleDefinitionName = "Oqtane.Modules.HtmlText, Oqtane.Client", Title = "Secure Content", Pane = PaneNames.Admin,
|
||||
ModulePermissions = new List<Permission> {
|
||||
new Permission(PermissionNames.View, RoleNames.Registered, true),
|
||||
new Permission(PermissionNames.View, RoleNames.Admin, true),
|
||||
|
@ -118,7 +118,7 @@ namespace Oqtane.SiteTemplates
|
|||
new Permission(PermissionNames.Edit, RoleNames.Admin, true)
|
||||
}.EncodePermissions(),
|
||||
PageTemplateModules = new List<PageTemplateModule> {
|
||||
new PageTemplateModule { ModuleDefinitionName = "Oqtane.Modules.HtmlText, Oqtane.Client", Title = "My Page", Pane = "Content",
|
||||
new PageTemplateModule { ModuleDefinitionName = "Oqtane.Modules.HtmlText, Oqtane.Client", Title = "My Page", Pane = PaneNames.Admin,
|
||||
ModulePermissions = new List<Permission> {
|
||||
new Permission(PermissionNames.View, RoleNames.Everyone, true),
|
||||
new Permission(PermissionNames.View, RoleNames.Admin, true),
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Oqtane.Extensions;
|
||||
using Oqtane.Models;
|
||||
using Oqtane.Repository;
|
||||
using Oqtane.Shared;
|
||||
|
@ -25,80 +24,101 @@ namespace Oqtane.Infrastructure
|
|||
|
||||
public void Upgrade(Tenant tenant, string version)
|
||||
{
|
||||
// core framework upgrade logic - note that you can check if current tenant is Master if you only want to execute the logic once
|
||||
switch (version)
|
||||
// core framework upgrade logic - executed for every tenant
|
||||
using (var scope = _serviceScopeFactory.CreateScope())
|
||||
{
|
||||
case "0.9.0":
|
||||
// this code is commented out on purpose - it provides an example of how to programmatically add a page to all existing sites on upgrade
|
||||
var pageTemplates = new List<PageTemplate>();
|
||||
//pageTemplates.Add(new PageTemplate
|
||||
//{
|
||||
// Name = "Test",
|
||||
// Parent = "",
|
||||
// Path = "test",
|
||||
// Icon = Icons.Badge,
|
||||
// IsNavigation = true,
|
||||
// IsPersonalizable = false,
|
||||
// EditMode = false,
|
||||
// PagePermissions = new List<Permission>
|
||||
// {
|
||||
// new Permission(PermissionNames.View, RoleNames.Admin, true),
|
||||
// new Permission(PermissionNames.View, RoleNames.Everyone, true),
|
||||
// new Permission(PermissionNames.Edit, RoleNames.Admin, true)
|
||||
// }.EncodePermissions(),
|
||||
// PageTemplateModules = new List<PageTemplateModule>
|
||||
// {
|
||||
// new PageTemplateModule
|
||||
// {
|
||||
// ModuleDefinitionName = typeof(Oqtane.Modules.Admin.Login.Index).ToModuleDefinitionName(), Title = "Test", Pane = "Content",
|
||||
// ModulePermissions = new List<Permission>
|
||||
// {
|
||||
// new Permission(PermissionNames.View, RoleNames.Admin, true),
|
||||
// new Permission(PermissionNames.View, RoleNames.Everyone, true),
|
||||
// new Permission(PermissionNames.Edit, RoleNames.Admin, true)
|
||||
// }.EncodePermissions(),
|
||||
// Content = ""
|
||||
// }
|
||||
// }
|
||||
//});
|
||||
CreateSitePages(tenant, pageTemplates);
|
||||
break;
|
||||
case "2.0.2":
|
||||
if (tenant.Name == TenantNames.Master)
|
||||
{
|
||||
// remove Internal module template files as they are no longer supported
|
||||
var internalTemplatePath = Utilities.PathCombine(_environment.WebRootPath, "Modules", "Templates", "Internal", Path.DirectorySeparatorChar.ToString());
|
||||
if (Directory.Exists(internalTemplatePath))
|
||||
{
|
||||
Directory.Delete(internalTemplatePath, true);
|
||||
}
|
||||
}
|
||||
break;
|
||||
// set SiteState based on tenant
|
||||
var siteState = scope.ServiceProvider.GetRequiredService<SiteState>();
|
||||
siteState.Alias = new Alias { TenantId = tenant.TenantId };
|
||||
|
||||
switch (version)
|
||||
{
|
||||
case "1.0.0":
|
||||
Upgrade_1_0_0(tenant, scope);
|
||||
break;
|
||||
case "2.0.2":
|
||||
Upgrade_2_0_2(tenant, scope);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void CreateSitePages(Tenant tenant, List<PageTemplate> pageTemplates)
|
||||
private void Upgrade_1_0_0(Tenant tenant, IServiceScope scope)
|
||||
{
|
||||
var pageTemplates = new List<PageTemplate>();
|
||||
|
||||
// **Note: this code is commented out on purpose - it provides an example of how to programmatically add a page to all existing sites on upgrade
|
||||
|
||||
//pageTemplates.Add(new PageTemplate
|
||||
//{
|
||||
// Name = "Test",
|
||||
// Parent = "",
|
||||
// Path = "test",
|
||||
// Icon = Icons.Badge,
|
||||
// IsNavigation = true,
|
||||
// IsPersonalizable = false,
|
||||
// EditMode = false,
|
||||
// PagePermissions = new List<Permission>
|
||||
// {
|
||||
// new Permission(PermissionNames.View, RoleNames.Admin, true),
|
||||
// new Permission(PermissionNames.View, RoleNames.Everyone, true),
|
||||
// new Permission(PermissionNames.Edit, RoleNames.Admin, true)
|
||||
// }.EncodePermissions(),
|
||||
// PageTemplateModules = new List<PageTemplateModule>
|
||||
// {
|
||||
// new PageTemplateModule
|
||||
// {
|
||||
// ModuleDefinitionName = typeof(Oqtane.Modules.Admin.Login.Index).ToModuleDefinitionName(), Title = "Test", Pane = "Content",
|
||||
// ModulePermissions = new List<Permission>
|
||||
// {
|
||||
// new Permission(PermissionNames.View, RoleNames.Admin, true),
|
||||
// new Permission(PermissionNames.View, RoleNames.Everyone, true),
|
||||
// new Permission(PermissionNames.Edit, RoleNames.Admin, true)
|
||||
// }.EncodePermissions(),
|
||||
// Content = ""
|
||||
// }
|
||||
// }
|
||||
//});
|
||||
|
||||
CreateSitePages(scope, pageTemplates);
|
||||
}
|
||||
|
||||
private void Upgrade_2_0_2(Tenant tenant, IServiceScope scope)
|
||||
{
|
||||
if (tenant.Name == TenantNames.Master)
|
||||
{
|
||||
// remove Internal module template files as they are no longer supported
|
||||
var internalTemplatePath = Utilities.PathCombine(_environment.WebRootPath, "Modules", "Templates", "Internal", Path.DirectorySeparatorChar.ToString());
|
||||
if (Directory.Exists(internalTemplatePath))
|
||||
{
|
||||
try
|
||||
{
|
||||
Directory.Delete(internalTemplatePath, true);
|
||||
}
|
||||
catch
|
||||
{
|
||||
// error deleting directory
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// initialize SiteGuid
|
||||
var sites = scope.ServiceProvider.GetRequiredService<ISiteRepository>();
|
||||
foreach (Site site in sites.GetSites().ToList())
|
||||
{
|
||||
site.SiteGuid = System.Guid.NewGuid().ToString();
|
||||
sites.UpdateSite(site);
|
||||
}
|
||||
}
|
||||
|
||||
private void CreateSitePages(IServiceScope scope, List<PageTemplate> pageTemplates)
|
||||
{
|
||||
if (pageTemplates.Count != 0)
|
||||
{
|
||||
var processed = new List<Site>();
|
||||
foreach (Alias alias in _aliases.GetAliases().Where(item => item.TenantId == tenant.TenantId))
|
||||
var sites = scope.ServiceProvider.GetRequiredService<ISiteRepository>();
|
||||
foreach (Site site in sites.GetSites().ToList())
|
||||
{
|
||||
if (!processed.Exists(item => item.SiteId == alias.SiteId))
|
||||
{
|
||||
using (var scope = _serviceScopeFactory.CreateScope())
|
||||
{
|
||||
var siteState = scope.ServiceProvider.GetRequiredService<SiteState>();
|
||||
siteState.Alias = alias;
|
||||
var sites = scope.ServiceProvider.GetRequiredService<ISiteRepository>();
|
||||
var site = sites.GetSite(alias.SiteId);
|
||||
if (site != null)
|
||||
{
|
||||
sites.CreatePages(site, pageTemplates);
|
||||
}
|
||||
processed.Add(site);
|
||||
}
|
||||
}
|
||||
sites.CreatePages(site, pageTemplates);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
<PropertyGroup>
|
||||
<TargetFramework>net5.0</TargetFramework>
|
||||
<Configurations>Debug;Release</Configurations>
|
||||
<Version>2.0.1</Version>
|
||||
<Version>2.0.2</Version>
|
||||
<Product>Oqtane</Product>
|
||||
<Authors>Shaun Walker</Authors>
|
||||
<Company>.NET Foundation</Company>
|
||||
|
@ -12,7 +12,7 @@
|
|||
<PackageProjectUrl>https://www.oqtane.org</PackageProjectUrl>
|
||||
<RepositoryUrl>https://github.com/oqtane</RepositoryUrl>
|
||||
<RepositoryType>Git</RepositoryType>
|
||||
<PackageReleaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v2.0.1</PackageReleaseNotes>
|
||||
<PackageReleaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v2.0.2</PackageReleaseNotes>
|
||||
<RootNamespace>Oqtane</RootNamespace>
|
||||
<IsPackable>true</IsPackable>
|
||||
</PropertyGroup>
|
||||
|
@ -20,6 +20,9 @@
|
|||
<Compile Remove="wwwroot\Modules\Templates\**" />
|
||||
<Content Remove="wwwroot\Modules\Templates\**" />
|
||||
<EmbeddedResource Remove="wwwroot\Modules\Templates\**" />
|
||||
<Compile Remove="wwwroot\Themes\Templates\**" />
|
||||
<Content Remove="wwwroot\Themes\Templates\**" />
|
||||
<EmbeddedResource Remove="wwwroot\Themes\Templates\**" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Include="Scripts\Master.00.00.00.00.sql" />
|
||||
|
@ -36,6 +39,9 @@
|
|||
<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="Scripts\Tenant.02.00.02.01.sql" />
|
||||
<EmbeddedResource Include="Scripts\Tenant.02.00.02.02.sql" />
|
||||
<EmbeddedResource Include="Scripts\Tenant.02.00.02.03.sql" />
|
||||
<EmbeddedResource Include="Modules\HtmlText\Scripts\HtmlText.1.0.0.sql" />
|
||||
<EmbeddedResource Include="Modules\HtmlText\Scripts\HtmlText.Uninstall.sql" />
|
||||
</ItemGroup>
|
||||
|
@ -60,9 +66,11 @@
|
|||
<UpgradeFiles Include="$(ProjectDir)bin\Release\net5.0\Oqtane.Upgrade.dll" />
|
||||
<UpgradeFiles Include="$(ProjectDir)bin\Release\net5.0\Oqtane.Upgrade.pdb" />
|
||||
<UpgradeFiles Include="$(ProjectDir)bin\Release\net5.0\Oqtane.Upgrade.runtimeconfig.json" />
|
||||
<TemplateFiles Include="$(ProjectDir)wwwroot\Modules\Templates\**\*.*" />
|
||||
<ModuleTemplateFiles Include="$(ProjectDir)wwwroot\Modules\Templates\**\*.*" />
|
||||
<ThemeTemplateFiles Include="$(ProjectDir)wwwroot\Themes\Templates\**\*.*" />
|
||||
</ItemGroup>
|
||||
<Target Name="AddPayloadsFolder" AfterTargets="Publish">
|
||||
<Copy SourceFiles="@(UpgradeFiles)" DestinationFiles="@(UpgradeFiles->'$(PublishDir)%(RecursiveDir)%(Filename)%(Extension)')" SkipUnchangedFiles="false" />
|
||||
<Copy SourceFiles="@(TemplateFiles)" DestinationFiles="@(TemplateFiles->'$(PublishDir)wwwroot\Modules\Templates\%(RecursiveDir)%(Filename)%(Extension)')" SkipUnchangedFiles="false" />
|
||||
<Copy SourceFiles="@(ModuleTemplateFiles)" DestinationFiles="@(ModuleTemplateFiles->'$(PublishDir)wwwroot\Modules\Templates\%(RecursiveDir)%(Filename)%(Extension)')" SkipUnchangedFiles="false" />
|
||||
<Copy SourceFiles="@(ThemeTemplateFiles)" DestinationFiles="@(ThemeTemplateFiles->'$(PublishDir)wwwroot\Themes\Templates\%(RecursiveDir)%(Filename)%(Extension)')" SkipUnchangedFiles="false" />
|
||||
</Target></Project>
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
<!-- stub the PWA manifest but defer the assignment of href -->
|
||||
<link id="app-manifest" rel="manifest" />
|
||||
<link rel="stylesheet" href="css/app.css" />
|
||||
<script src="js/app.js"></script>
|
||||
<script src="js/loadjs.min.js"></script>
|
||||
@Html.Raw(@Model.HeadResources)
|
||||
</head>
|
||||
|
|
|
@ -68,7 +68,7 @@ namespace Oqtane.Repository
|
|||
{
|
||||
new PageTemplateModule
|
||||
{
|
||||
ModuleDefinitionName = typeof(Oqtane.Modules.Admin.Login.Index).ToModuleDefinitionName(), Title = "User Login", Pane = "Content",
|
||||
ModuleDefinitionName = typeof(Oqtane.Modules.Admin.Login.Index).ToModuleDefinitionName(), Title = "User Login", Pane = PaneNames.Admin,
|
||||
ModulePermissions = new List<Permission>
|
||||
{
|
||||
new Permission(PermissionNames.View, RoleNames.Admin, true),
|
||||
|
@ -97,7 +97,7 @@ namespace Oqtane.Repository
|
|||
{
|
||||
new PageTemplateModule
|
||||
{
|
||||
ModuleDefinitionName = typeof(Oqtane.Modules.Admin.Register.Index).ToModuleDefinitionName(), Title = "User Registration", Pane = "Content",
|
||||
ModuleDefinitionName = typeof(Oqtane.Modules.Admin.Register.Index).ToModuleDefinitionName(), Title = "User Registration", Pane = PaneNames.Admin,
|
||||
ModulePermissions = new List<Permission>
|
||||
{
|
||||
new Permission(PermissionNames.View, RoleNames.Admin, true),
|
||||
|
@ -127,7 +127,7 @@ namespace Oqtane.Repository
|
|||
{
|
||||
new PageTemplateModule
|
||||
{
|
||||
ModuleDefinitionName = typeof(Oqtane.Modules.Admin.Reset.Index).ToModuleDefinitionName(), Title = "Password Reset", Pane = "Content",
|
||||
ModuleDefinitionName = typeof(Oqtane.Modules.Admin.Reset.Index).ToModuleDefinitionName(), Title = "Password Reset", Pane = PaneNames.Admin,
|
||||
ModulePermissions = new List<Permission>
|
||||
{
|
||||
new Permission(PermissionNames.View, RoleNames.Admin, true),
|
||||
|
@ -156,7 +156,7 @@ namespace Oqtane.Repository
|
|||
{
|
||||
new PageTemplateModule
|
||||
{
|
||||
ModuleDefinitionName = typeof(Oqtane.Modules.Admin.UserProfile.Index).ToModuleDefinitionName(), Title = "User Profile", Pane = "Content",
|
||||
ModuleDefinitionName = typeof(Oqtane.Modules.Admin.UserProfile.Index).ToModuleDefinitionName(), Title = "User Profile", Pane = PaneNames.Admin,
|
||||
ModulePermissions = new List<Permission>
|
||||
{
|
||||
new Permission(PermissionNames.View, RoleNames.Admin, true),
|
||||
|
@ -181,7 +181,7 @@ namespace Oqtane.Repository
|
|||
{
|
||||
new PageTemplateModule
|
||||
{
|
||||
ModuleDefinitionName = typeof(Oqtane.Modules.Admin.Dashboard.Index).ToModuleDefinitionName(), Title = "Admin Dashboard", Pane = "Content",
|
||||
ModuleDefinitionName = typeof(Oqtane.Modules.Admin.Dashboard.Index).ToModuleDefinitionName(), Title = "Admin Dashboard", Pane = PaneNames.Admin,
|
||||
ModulePermissions = new List<Permission>
|
||||
{
|
||||
new Permission(PermissionNames.View, RoleNames.Admin, true),
|
||||
|
@ -208,7 +208,7 @@ namespace Oqtane.Repository
|
|||
{
|
||||
new PageTemplateModule
|
||||
{
|
||||
ModuleDefinitionName = typeof(Oqtane.Modules.Admin.Site.Index).ToModuleDefinitionName(), Title = "Site Settings", Pane = "Content",
|
||||
ModuleDefinitionName = typeof(Oqtane.Modules.Admin.Site.Index).ToModuleDefinitionName(), Title = "Site Settings", Pane = PaneNames.Admin,
|
||||
ModulePermissions = new List<Permission>
|
||||
{
|
||||
new Permission(PermissionNames.View, RoleNames.Admin, true),
|
||||
|
@ -235,7 +235,7 @@ namespace Oqtane.Repository
|
|||
{
|
||||
new PageTemplateModule
|
||||
{
|
||||
ModuleDefinitionName = typeof(Oqtane.Modules.Admin.Pages.Index).ToModuleDefinitionName(), Title = "Page Management", Pane = "Content",
|
||||
ModuleDefinitionName = typeof(Oqtane.Modules.Admin.Pages.Index).ToModuleDefinitionName(), Title = "Page Management", Pane = PaneNames.Admin,
|
||||
ModulePermissions = new List<Permission>
|
||||
{
|
||||
new Permission(PermissionNames.View, RoleNames.Admin, true),
|
||||
|
@ -262,7 +262,7 @@ namespace Oqtane.Repository
|
|||
{
|
||||
new PageTemplateModule
|
||||
{
|
||||
ModuleDefinitionName = typeof(Oqtane.Modules.Admin.Users.Index).ToModuleDefinitionName(), Title = "User Management", Pane = "Content",
|
||||
ModuleDefinitionName = typeof(Oqtane.Modules.Admin.Users.Index).ToModuleDefinitionName(), Title = "User Management", Pane = PaneNames.Admin,
|
||||
ModulePermissions = new List<Permission>
|
||||
{
|
||||
new Permission(PermissionNames.View, RoleNames.Admin, true),
|
||||
|
@ -289,7 +289,7 @@ namespace Oqtane.Repository
|
|||
{
|
||||
new PageTemplateModule
|
||||
{
|
||||
ModuleDefinitionName = typeof(Oqtane.Modules.Admin.Profiles.Index).ToModuleDefinitionName(), Title = "Profile Management", Pane = "Content",
|
||||
ModuleDefinitionName = typeof(Oqtane.Modules.Admin.Profiles.Index).ToModuleDefinitionName(), Title = "Profile Management", Pane = PaneNames.Admin,
|
||||
ModulePermissions = new List<Permission>
|
||||
{
|
||||
new Permission(PermissionNames.View, RoleNames.Admin, true),
|
||||
|
@ -316,7 +316,7 @@ namespace Oqtane.Repository
|
|||
{
|
||||
new PageTemplateModule
|
||||
{
|
||||
ModuleDefinitionName = typeof(Oqtane.Modules.Admin.Roles.Index).ToModuleDefinitionName(), Title = "Role Management", Pane = "Content",
|
||||
ModuleDefinitionName = typeof(Oqtane.Modules.Admin.Roles.Index).ToModuleDefinitionName(), Title = "Role Management", Pane = PaneNames.Admin,
|
||||
ModulePermissions = new List<Permission>
|
||||
{
|
||||
new Permission(PermissionNames.View, RoleNames.Admin, true),
|
||||
|
@ -343,7 +343,7 @@ namespace Oqtane.Repository
|
|||
{
|
||||
new PageTemplateModule
|
||||
{
|
||||
ModuleDefinitionName = typeof(Oqtane.Modules.Admin.Files.Index).ToModuleDefinitionName(), Title = "File Management", Pane = "Content",
|
||||
ModuleDefinitionName = typeof(Oqtane.Modules.Admin.Files.Index).ToModuleDefinitionName(), Title = "File Management", Pane = PaneNames.Admin,
|
||||
ModulePermissions = new List<Permission>
|
||||
{
|
||||
new Permission(PermissionNames.View, RoleNames.Admin, true),
|
||||
|
@ -370,7 +370,7 @@ namespace Oqtane.Repository
|
|||
{
|
||||
new PageTemplateModule
|
||||
{
|
||||
ModuleDefinitionName = typeof(Oqtane.Modules.Admin.RecycleBin.Index).ToModuleDefinitionName(), Title = "Recycle Bin", Pane = "Content",
|
||||
ModuleDefinitionName = typeof(Oqtane.Modules.Admin.RecycleBin.Index).ToModuleDefinitionName(), Title = "Recycle Bin", Pane = PaneNames.Admin,
|
||||
ModulePermissions = new List<Permission>
|
||||
{
|
||||
new Permission(PermissionNames.View, RoleNames.Admin, true),
|
||||
|
@ -399,7 +399,7 @@ namespace Oqtane.Repository
|
|||
{
|
||||
new PageTemplateModule
|
||||
{
|
||||
ModuleDefinitionName = typeof(Oqtane.Modules.Admin.Logs.Index).ToModuleDefinitionName(), Title = "Event Log", Pane = "Content",
|
||||
ModuleDefinitionName = typeof(Oqtane.Modules.Admin.Logs.Index).ToModuleDefinitionName(), Title = "Event Log", Pane = PaneNames.Admin,
|
||||
ModulePermissions = new List<Permission>
|
||||
{
|
||||
new Permission(PermissionNames.View, RoleNames.Host, true),
|
||||
|
@ -421,7 +421,7 @@ namespace Oqtane.Repository
|
|||
{
|
||||
new PageTemplateModule
|
||||
{
|
||||
ModuleDefinitionName = typeof(Oqtane.Modules.Admin.Sites.Index).ToModuleDefinitionName(), Title = "Site Management", Pane = "Content",
|
||||
ModuleDefinitionName = typeof(Oqtane.Modules.Admin.Sites.Index).ToModuleDefinitionName(), Title = "Site Management", Pane = PaneNames.Admin,
|
||||
ModulePermissions = new List<Permission>
|
||||
{
|
||||
new Permission(PermissionNames.View, RoleNames.Host, true),
|
||||
|
@ -443,7 +443,7 @@ namespace Oqtane.Repository
|
|||
{
|
||||
new PageTemplateModule
|
||||
{
|
||||
ModuleDefinitionName = typeof(Oqtane.Modules.Admin.ModuleDefinitions.Index).ToModuleDefinitionName(), Title = "Module Management", Pane = "Content",
|
||||
ModuleDefinitionName = typeof(Oqtane.Modules.Admin.ModuleDefinitions.Index).ToModuleDefinitionName(), Title = "Module Management", Pane = PaneNames.Admin,
|
||||
ModulePermissions = new List<Permission>
|
||||
{
|
||||
new Permission(PermissionNames.View, RoleNames.Host, true),
|
||||
|
@ -465,7 +465,7 @@ namespace Oqtane.Repository
|
|||
{
|
||||
new PageTemplateModule
|
||||
{
|
||||
ModuleDefinitionName = typeof(Oqtane.Modules.Admin.Themes.Index).ToModuleDefinitionName(), Title = "Theme Management", Pane = "Content",
|
||||
ModuleDefinitionName = typeof(Oqtane.Modules.Admin.Themes.Index).ToModuleDefinitionName(), Title = "Theme Management", Pane = PaneNames.Admin,
|
||||
ModulePermissions = new List<Permission>
|
||||
{
|
||||
new Permission(PermissionNames.View, RoleNames.Host, true),
|
||||
|
@ -494,7 +494,7 @@ namespace Oqtane.Repository
|
|||
{
|
||||
new PageTemplateModule
|
||||
{
|
||||
ModuleDefinitionName = typeof(Oqtane.Modules.Admin.Languages.Index).ToModuleDefinitionName(), Title = "Language Management", Pane = "Content",
|
||||
ModuleDefinitionName = typeof(Oqtane.Modules.Admin.Languages.Index).ToModuleDefinitionName(), Title = "Language Management", Pane = PaneNames.Admin,
|
||||
ModulePermissions = new List<Permission>
|
||||
{
|
||||
new Permission(PermissionNames.View, RoleNames.Host, true),
|
||||
|
@ -518,7 +518,7 @@ namespace Oqtane.Repository
|
|||
{
|
||||
new PageTemplateModule
|
||||
{
|
||||
ModuleDefinitionName = typeof(Oqtane.Modules.Admin.Jobs.Index).ToModuleDefinitionName(), Title = "Scheduled Jobs", Pane = "Content",
|
||||
ModuleDefinitionName = typeof(Oqtane.Modules.Admin.Jobs.Index).ToModuleDefinitionName(), Title = "Scheduled Jobs", Pane = PaneNames.Admin,
|
||||
ModulePermissions = new List<Permission>
|
||||
{
|
||||
new Permission(PermissionNames.View, RoleNames.Host, true),
|
||||
|
@ -540,7 +540,7 @@ namespace Oqtane.Repository
|
|||
{
|
||||
new PageTemplateModule
|
||||
{
|
||||
ModuleDefinitionName = typeof(Oqtane.Modules.Admin.Sql.Index).ToModuleDefinitionName(), Title = "Sql Management", Pane = "Content",
|
||||
ModuleDefinitionName = typeof(Oqtane.Modules.Admin.Sql.Index).ToModuleDefinitionName(), Title = "Sql Management", Pane = PaneNames.Admin,
|
||||
ModulePermissions = new List<Permission>
|
||||
{
|
||||
new Permission(PermissionNames.View, RoleNames.Host, true),
|
||||
|
@ -562,7 +562,7 @@ namespace Oqtane.Repository
|
|||
{
|
||||
new PageTemplateModule
|
||||
{
|
||||
ModuleDefinitionName = typeof(Oqtane.Modules.Admin.SystemInfo.Index).ToModuleDefinitionName(), Title = "System Info", Pane = "Content",
|
||||
ModuleDefinitionName = typeof(Oqtane.Modules.Admin.SystemInfo.Index).ToModuleDefinitionName(), Title = "System Info", Pane = PaneNames.Admin,
|
||||
ModulePermissions = new List<Permission>
|
||||
{
|
||||
new Permission(PermissionNames.View, RoleNames.Host, true),
|
||||
|
@ -584,7 +584,7 @@ namespace Oqtane.Repository
|
|||
{
|
||||
new PageTemplateModule
|
||||
{
|
||||
ModuleDefinitionName = typeof(Oqtane.Modules.Admin.Upgrade.Index).ToModuleDefinitionName(), Title = "System Update", Pane = "Content",
|
||||
ModuleDefinitionName = typeof(Oqtane.Modules.Admin.Upgrade.Index).ToModuleDefinitionName(), Title = "System Update", Pane = PaneNames.Admin,
|
||||
ModulePermissions = new List<Permission>
|
||||
{
|
||||
new Permission(PermissionNames.View, RoleNames.Host, true),
|
||||
|
@ -605,7 +605,7 @@ namespace Oqtane.Repository
|
|||
|
||||
public Site AddSite(Site site)
|
||||
{
|
||||
|
||||
site.SiteGuid = System.Guid.NewGuid().ToString();
|
||||
_db.Site.Add(site);
|
||||
_db.SaveChanges();
|
||||
CreateSite(site);
|
||||
|
@ -745,7 +745,6 @@ namespace Oqtane.Repository
|
|||
Url = "",
|
||||
IsNavigation = pagetemplate.IsNavigation,
|
||||
ThemeType = "",
|
||||
LayoutType = "",
|
||||
DefaultContainerType = "",
|
||||
Icon = pagetemplate.Icon,
|
||||
Permissions = pagetemplate.PagePermissions,
|
||||
|
|
|
@ -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<ThemeControl>();
|
||||
theme.Layouts = new List<ThemeControl>();
|
||||
theme.Containers = new List<ThemeControl>();
|
||||
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();
|
||||
|
|
10
Oqtane.Server/Scripts/Tenant.02.00.02.01.sql
Normal file
10
Oqtane.Server/Scripts/Tenant.02.00.02.01.sql
Normal file
|
@ -0,0 +1,10 @@
|
|||
/*
|
||||
|
||||
Version 2.0.2 Tenant migration script
|
||||
|
||||
*/
|
||||
|
||||
ALTER TABLE [dbo].[Site] ADD
|
||||
[SiteGuid] [char](36) NULL
|
||||
GO
|
||||
|
20
Oqtane.Server/Scripts/Tenant.02.00.02.02.sql
Normal file
20
Oqtane.Server/Scripts/Tenant.02.00.02.02.sql
Normal file
|
@ -0,0 +1,20 @@
|
|||
/*
|
||||
|
||||
Version 2.0.2 Tenant migration script
|
||||
|
||||
*/
|
||||
|
||||
UPDATE [dbo].[Site] SET DefaultContainerType = 'Oqtane.Themes.OqtaneTheme.DefaultTitle, Oqtane.Client' WHERE DefaultContainerType = 'Oqtane.Themes.OqtaneTheme.Container, Oqtane.Client';
|
||||
GO
|
||||
UPDATE [dbo].[Site] SET DefaultContainerType = 'Oqtane.Themes.OqtaneTheme.DefaultNoTitle, Oqtane.Client' WHERE DefaultContainerType = 'Oqtane.Themes.OqtaneTheme.NoTitle, Oqtane.Client';
|
||||
GO
|
||||
|
||||
UPDATE [dbo].[Page] SET DefaultContainerType = 'Oqtane.Themes.OqtaneTheme.DefaultTitle, Oqtane.Client' WHERE DefaultContainerType = 'Oqtane.Themes.OqtaneTheme.Container, Oqtane.Client';
|
||||
GO
|
||||
UPDATE [dbo].[Page] SET DefaultContainerType = 'Oqtane.Themes.OqtaneTheme.DefaultNoTitle, Oqtane.Client' WHERE DefaultContainerType = 'Oqtane.Themes.OqtaneTheme.NoTitle, Oqtane.Client';
|
||||
GO
|
||||
|
||||
UPDATE [dbo].[PageModule] SET ContainerType = 'Oqtane.Themes.OqtaneTheme.DefaultTitle, Oqtane.Client' WHERE ContainerType = 'Oqtane.Themes.OqtaneTheme.Container, Oqtane.Client';
|
||||
GO
|
||||
UPDATE [dbo].[PageModule] SET ContainerType = 'Oqtane.Themes.OqtaneTheme.DefaultNoTitle, Oqtane.Client' WHERE ContainerType = 'Oqtane.Themes.OqtaneTheme.NoTitle, Oqtane.Client';
|
||||
GO
|
31
Oqtane.Server/Scripts/Tenant.02.00.02.03.sql
Normal file
31
Oqtane.Server/Scripts/Tenant.02.00.02.03.sql
Normal file
|
@ -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
|
|
@ -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.
|
||||
|
|
|
@ -74,22 +74,29 @@
|
|||
{
|
||||
try
|
||||
{
|
||||
if (PageState.Action == "Add")
|
||||
if (!string.IsNullOrEmpty(_name))
|
||||
{
|
||||
[Module] [Module] = new [Module]();
|
||||
[Module].ModuleId = ModuleState.ModuleId;
|
||||
[Module].Name = _name;
|
||||
[Module] = await [Module]Service.Add[Module]Async([Module]);
|
||||
await logger.LogInformation("[Module] Added {[Module]}", [Module]);
|
||||
if (PageState.Action == "Add")
|
||||
{
|
||||
[Module] [Module] = new [Module]();
|
||||
[Module].ModuleId = ModuleState.ModuleId;
|
||||
[Module].Name = _name;
|
||||
[Module] = await [Module]Service.Add[Module]Async([Module]);
|
||||
await logger.LogInformation("[Module] Added {[Module]}", [Module]);
|
||||
}
|
||||
else
|
||||
{
|
||||
[Module] [Module] = await [Module]Service.Get[Module]Async(_id, ModuleState.ModuleId);
|
||||
[Module].Name = _name;
|
||||
await [Module]Service.Update[Module]Async([Module]);
|
||||
await logger.LogInformation("[Module] Updated {[Module]}", [Module]);
|
||||
}
|
||||
NavigationManager.NavigateTo(NavigateUrl());
|
||||
}
|
||||
else
|
||||
{
|
||||
[Module] [Module] = await [Module]Service.Get[Module]Async(_id, ModuleState.ModuleId);
|
||||
[Module].Name = _name;
|
||||
await [Module]Service.Update[Module]Async([Module]);
|
||||
await logger.LogInformation("[Module] Updated {[Module]}", [Module]);
|
||||
AddModuleMessage("The Name Is Required", MessageType.Warning);
|
||||
}
|
||||
NavigationManager.NavigateTo(NavigateUrl());
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
|
|
@ -36,40 +36,6 @@ else
|
|||
}
|
||||
}
|
||||
|
||||
<!-- The content below is for informational purposes only and can be safely removed -->
|
||||
|
||||
<hr />
|
||||
[Module] Module Created Successfully. Use Edit Mode To Add A [Module]. You Can Access The Files At The Following Locations:<br /><br />
|
||||
[RootPath]Client\<br />
|
||||
- [Owner].[Module].Client.csproj - client project<br />
|
||||
- _Imports.razor - global imports for module components<br />
|
||||
- Edit.razor - component for adding or editing content<br />
|
||||
- Index.razor - main component for your module **the content you are reading is in this file**<br />
|
||||
- ModuleInfo.cs - implements IModule interface to provide configuration settings for your module<br />
|
||||
- Settings.razor - component for managing module settings<br />
|
||||
- Services\I[Module]Service.cs - interface for defining service API methods<br />
|
||||
- Services\[Module]Service.cs - implements service API interface methods<br /><br />
|
||||
[RootPath]Package\<br />
|
||||
- [Owner].[Module].nuspec - nuget manifest for packaging module<br />
|
||||
- [Owner].[Module].Package.csproj - packaging project<br />
|
||||
- debug.cmd - copies assemblies to Oqtane bin folder when in Debug mode<br />
|
||||
- release.cmd - creates nuget package and deploys to Oqtane wwwroot/modules folder when in Release mode<br /><br />
|
||||
[RootPath]Server\<br />
|
||||
- [Owner].[Module].Server.csproj - server project<br />
|
||||
- Controllers\[Module]Controller.cs - API methods implemented using a REST pattern<br />
|
||||
- Manager\[Module]Manager.cs - implements optional module interfaces for features such as import/export of content<br />
|
||||
- Repository\I[Module]Repository.cs - interface for defining repository methods<br />
|
||||
- Repository\[Module]Respository.cs - implements repository interface methods for data access using EF Core<br />
|
||||
- Repository\[Module]Context.cs - provides a DB Context for data access<br />
|
||||
- Scripts\[Owner].[Module].1.0.0.sql - database schema definition script<br />
|
||||
- Scripts\[Owner].[Module].Uninstall.sql - database uninstall script<br />
|
||||
- wwwroot\Module.css - module style sheet<br /><br />
|
||||
[RootPath]Shared\<br />
|
||||
- [Owner].[Module].csproj - shared project<br />
|
||||
- Models\[Module].cs - model definition<br /><br />
|
||||
|
||||
<!-- The content above is for informational purposes only and can be safely removed -->
|
||||
|
||||
@code {
|
||||
public override List<Resource> Resources => new List<Resource>()
|
||||
{
|
||||
|
|
|
@ -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 {
|
||||
|
|
4
Oqtane.Server/wwwroot/Themes/Templates/External/Client/AssemblyInfo.cs
vendored
Normal file
4
Oqtane.Server/wwwroot/Themes/Templates/External/Client/AssemblyInfo.cs
vendored
Normal file
|
@ -0,0 +1,4 @@
|
|||
using System.Resources;
|
||||
using Microsoft.Extensions.Localization;
|
||||
|
||||
[assembly: RootNamespace("[Owner].[Theme].Client")]
|
|
@ -1,5 +1,6 @@
|
|||
@namespace Oqtane.Themes.OqtaneTheme
|
||||
@namespace [Owner].[Theme]
|
||||
@inherits ContainerBase
|
||||
|
||||
<div class="container">
|
||||
<div class="row px-4">
|
||||
<div class="d-flex flex-nowrap">
|
||||
|
@ -15,5 +16,5 @@
|
|||
</div>
|
||||
|
||||
@code {
|
||||
public override string Name => "Standard Header";
|
||||
public override string Name => "Container1";
|
||||
}
|
15
Oqtane.Server/wwwroot/Themes/Templates/External/Client/ThemeInfo.cs
vendored
Normal file
15
Oqtane.Server/wwwroot/Themes/Templates/External/Client/ThemeInfo.cs
vendored
Normal file
|
@ -0,0 +1,15 @@
|
|||
using Oqtane.Models;
|
||||
using Oqtane.Themes;
|
||||
|
||||
namespace [Owner].[Theme]
|
||||
{
|
||||
public class ThemeInfo : ITheme
|
||||
{
|
||||
public Theme Theme => new Theme
|
||||
{
|
||||
Name = "[Theme]",
|
||||
Version = "1.0.0"
|
||||
};
|
||||
|
||||
}
|
||||
}
|
109
Oqtane.Server/wwwroot/Themes/Templates/External/Client/Themes/Theme1.razor
vendored
Normal file
109
Oqtane.Server/wwwroot/Themes/Templates/External/Client/Themes/Theme1.razor
vendored
Normal file
|
@ -0,0 +1,109 @@
|
|||
@namespace [Owner].[Theme]
|
||||
@inherits ThemeBase
|
||||
|
||||
<main role="main">
|
||||
<nav class="navbar navbar-expand-md navbar-dark bg-primary fixed-top">
|
||||
<Logo /><Menu Orientation="Horizontal" />
|
||||
<div class="controls ml-md-auto">
|
||||
<div class="controls-group"><UserProfile /> <Login /> <ControlPanel /></div>
|
||||
</div>
|
||||
</nav>
|
||||
<div class="content">
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<Pane Name="@PaneNames.Admin" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<Pane Name="Top Full Width" />
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<Pane Name="Top 100%" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<Pane Name="Left 50%" />
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<Pane Name="Right 50%" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-4">
|
||||
<Pane Name="Left 33%" />
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<Pane Name="Center 33%" />
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<Pane Name="Right 33%" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-3">
|
||||
<Pane Name="Left Outer 25%" />
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<Pane Name="Left Inner 25%" />
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<Pane Name="Right Inner 25%" />
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<Pane Name="Right Outer 25%" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-3">
|
||||
<Pane Name="Left 25%" />
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<Pane Name="Center 50%" />
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<Pane Name="Right 25%" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-8">
|
||||
<Pane Name="Left Sidebar 66%" />
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<Pane Name="Right Sidebar 33%" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-4">
|
||||
<Pane Name="Left Sidebar 33%" />
|
||||
</div>
|
||||
<div class="col-md-8">
|
||||
<Pane Name="Right Sidebar 66%" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<Pane Name="Bottom 100%" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<Pane Name="Bottom Full Width" />
|
||||
</div>
|
||||
</main>
|
||||
|
||||
@code {
|
||||
public override string Name => "Theme1";
|
||||
|
||||
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<Resource> Resources => new List<Resource>()
|
||||
{
|
||||
new Resource { ResourceType = ResourceType.Stylesheet, Url = "https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css", Integrity = "sha384-9aIt2nRpC12Uk9gS9baDl411NQApFmC26EwAOH8WgZl5MYYxFfc+NcPb1dKGj7Sk", 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" }
|
||||
};
|
||||
}
|
34
Oqtane.Server/wwwroot/Themes/Templates/External/Client/[Owner].[Theme].Client.csproj
vendored
Normal file
34
Oqtane.Server/wwwroot/Themes/Templates/External/Client/[Owner].[Theme].Client.csproj
vendored
Normal file
|
@ -0,0 +1,34 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk.Razor">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net5.0</TargetFramework>
|
||||
<RazorLangVersion>3.0</RazorLangVersion>
|
||||
<Version>1.0.0</Version>
|
||||
<Authors>[Owner]</Authors>
|
||||
<Company>[Owner]</Company>
|
||||
<Description>[Description]</Description>
|
||||
<Product>[Owner].[Theme]</Product>
|
||||
<Copyright>[Owner]</Copyright>
|
||||
<AssemblyName>[Owner].[Theme].Client.Oqtane</AssemblyName>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="5.0.0" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" Version="5.0.0" PrivateAssets="all" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.Authentication" Version="5.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Localization" Version="5.0.0" />
|
||||
<PackageReference Include="System.Net.Http.Json" Version="5.0.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
[ClientReference]
|
||||
[SharedReference]
|
||||
</ItemGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
<!-- there may be other elements here -->
|
||||
<BlazorWebAssemblyEnableLinking>false</BlazorWebAssemblyEnableLinking>
|
||||
<GeneratePackageOnBuild>false</GeneratePackageOnBuild>
|
||||
</PropertyGroup>
|
||||
|
||||
</Project>
|
21
Oqtane.Server/wwwroot/Themes/Templates/External/Client/_Imports.razor
vendored
Normal file
21
Oqtane.Server/wwwroot/Themes/Templates/External/Client/_Imports.razor
vendored
Normal file
|
@ -0,0 +1,21 @@
|
|||
@using System
|
||||
@using System.Linq
|
||||
@using System.Collections.Generic
|
||||
@using System.Net.Http
|
||||
@using System.Net.Http.Json
|
||||
|
||||
@using Microsoft.AspNetCore.Components.Routing
|
||||
@using Microsoft.AspNetCore.Components.Web
|
||||
@using Microsoft.JSInterop
|
||||
|
||||
@using Oqtane.Models
|
||||
@using Oqtane.Modules
|
||||
@using Oqtane.Modules.Controls
|
||||
@using Oqtane.Providers
|
||||
@using Oqtane.Security
|
||||
@using Oqtane.Services
|
||||
@using Oqtane.Shared
|
||||
@using Oqtane.Themes
|
||||
@using Oqtane.Themes.Controls
|
||||
@using Oqtane.UI
|
||||
@using Oqtane.Enums
|
83
Oqtane.Server/wwwroot/Themes/Templates/External/Client/wwwroot/Themes/[Owner].[Theme]/Theme.css
vendored
Normal file
83
Oqtane.Server/wwwroot/Themes/Templates/External/Client/wwwroot/Themes/[Owner].[Theme]/Theme.css
vendored
Normal file
|
@ -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;
|
||||
}
|
||||
}
|
17
Oqtane.Server/wwwroot/Themes/Templates/External/Package/[Owner].[Theme].Package.csproj
vendored
Normal file
17
Oqtane.Server/wwwroot/Themes/Templates/External/Package/[Owner].[Theme].Package.csproj
vendored
Normal file
|
@ -0,0 +1,17 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net5.0</TargetFramework>
|
||||
<GeneratePackageOnBuild>false</GeneratePackageOnBuild>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Client\[Owner].[Theme].Client.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<Target Name="PostBuild" AfterTargets="PostBuildEvent">
|
||||
<Exec Command="IF $(ConfigurationName) == Debug (debug.cmd)" />
|
||||
<Exec Command="IF $(ConfigurationName) == Release (release.cmd)" />
|
||||
</Target>
|
||||
|
||||
</Project>
|
27
Oqtane.Server/wwwroot/Themes/Templates/External/Package/[Owner].[Theme].nuspec
vendored
Normal file
27
Oqtane.Server/wwwroot/Themes/Templates/External/Package/[Owner].[Theme].nuspec
vendored
Normal file
|
@ -0,0 +1,27 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
|
||||
<metadata>
|
||||
<id>[Owner].[Theme]</id>
|
||||
<version>1.0.0</version>
|
||||
<authors>[Owner]</authors>
|
||||
<owners>[Owner]</owners>
|
||||
<title>[Theme]</title>
|
||||
<description>[Theme]</description>
|
||||
<copyright>[Owner]</copyright>
|
||||
<requireLicenseAcceptance>false</requireLicenseAcceptance>
|
||||
<license type="expression">MIT</license>
|
||||
<projectUrl>https://github.com/oqtane/oqtane.framework</projectUrl>
|
||||
<iconUrl>https://www.oqtane.org/Portals/0/icon.jpg</iconUrl>
|
||||
<tags>oqtane module</tags>
|
||||
<releaseNotes></releaseNotes>
|
||||
<summary></summary>
|
||||
<dependencies>
|
||||
<dependency id="Oqtane.Framework" version="[FrameworkVersion]" />
|
||||
</dependencies>
|
||||
</metadata>
|
||||
<files>
|
||||
<file src="..\Client\bin\Release\net5.0\[Owner].[Theme].Client.Oqtane.dll" target="lib\net5.0" />
|
||||
<file src="..\Client\bin\Release\net5.0\[Owner].[Theme].Client.Oqtane.pdb" target="lib\net5.0" />
|
||||
<file src="..\Client\wwwroot\**\*.*" target="wwwroot" />
|
||||
</files>
|
||||
</package>
|
3
Oqtane.Server/wwwroot/Themes/Templates/External/Package/debug.cmd
vendored
Normal file
3
Oqtane.Server/wwwroot/Themes/Templates/External/Package/debug.cmd
vendored
Normal file
|
@ -0,0 +1,3 @@
|
|||
XCOPY "..\Client\bin\Debug\net5.0\[Owner].[Theme].Client.Oqtane.dll" "..\..\[RootFolder]\Oqtane.Server\bin\Debug\net5.0\" /Y
|
||||
XCOPY "..\Client\bin\Debug\net5.0\[Owner].[Theme].Client.Oqtane.pdb" "..\..\[RootFolder]\Oqtane.Server\bin\Debug\net5.0\" /Y
|
||||
XCOPY "..\Client\wwwroot\*" "..\..\[RootFolder]\Oqtane.Client\wwwroot\" /Y /S /I
|
2
Oqtane.Server/wwwroot/Themes/Templates/External/Package/release.cmd
vendored
Normal file
2
Oqtane.Server/wwwroot/Themes/Templates/External/Package/release.cmd
vendored
Normal file
|
@ -0,0 +1,2 @@
|
|||
"..\..\[RootFolder]\oqtane.package\nuget.exe" pack [Owner].[Theme].nuspec
|
||||
XCOPY "*.nupkg" "..\..\[RootFolder]\Oqtane.Server\wwwroot\Themes\" /Y
|
36
Oqtane.Server/wwwroot/Themes/Templates/External/[Owner].[Theme].sln
vendored
Normal file
36
Oqtane.Server/wwwroot/Themes/Templates/External/[Owner].[Theme].sln
vendored
Normal file
|
@ -0,0 +1,36 @@
|
|||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 16
|
||||
VisualStudioVersion = 16.0.28621.142
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "[Owner].[Theme].Client", "Client\[Owner].[Theme].Client.csproj", "{AA8E58A1-CD09-4208-BF66-A8BB341FD669}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "[Owner].[Theme].Package", "Package\[Owner].[Theme].Package.csproj", "{C5CE512D-CBB7-4545-AF0F-9B6591A0C3A7}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Release|Any CPU = Release|Any CPU
|
||||
Wasm|Any CPU = Wasm|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{AA8E58A1-CD09-4208-BF66-A8BB341FD669}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{AA8E58A1-CD09-4208-BF66-A8BB341FD669}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{AA8E58A1-CD09-4208-BF66-A8BB341FD669}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{AA8E58A1-CD09-4208-BF66-A8BB341FD669}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{AA8E58A1-CD09-4208-BF66-A8BB341FD669}.Wasm|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{AA8E58A1-CD09-4208-BF66-A8BB341FD669}.Wasm|Any CPU.Build.0 = Release|Any CPU
|
||||
{C5CE512D-CBB7-4545-AF0F-9B6591A0C3A7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{C5CE512D-CBB7-4545-AF0F-9B6591A0C3A7}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{C5CE512D-CBB7-4545-AF0F-9B6591A0C3A7}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{C5CE512D-CBB7-4545-AF0F-9B6591A0C3A7}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{C5CE512D-CBB7-4545-AF0F-9B6591A0C3A7}.Wasm|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{C5CE512D-CBB7-4545-AF0F-9B6591A0C3A7}.Wasm|Any CPU.Build.0 = Debug|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {1D016F15-46FE-4726-8DFD-2E4FD4DC7668}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user