support for module header and footer content
This commit is contained in:
parent
9000f05961
commit
57d443be8d
@ -97,6 +97,23 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<br />
|
||||||
|
<Section Name="ModuleContent" Heading="Content" ResourceKey="ModuleContent">
|
||||||
|
<div class="container">
|
||||||
|
<div class="row mb-1 align-items-center">
|
||||||
|
<Label Class="col-sm-3" For="header" HelpText="Optionally provide content to be injected above the module instance" ResourceKey="Header">Header: </Label>
|
||||||
|
<div class="col-sm-9">
|
||||||
|
<textarea id="header" class="form-control" @bind="@_header" rows="3" maxlength="4000"></textarea>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row mb-1 align-items-center">
|
||||||
|
<Label Class="col-sm-3" For="footer" HelpText="Optionally provide content to be injected below the module instance" ResourceKey="Footer">Footer: </Label>
|
||||||
|
<div class="col-sm-9">
|
||||||
|
<textarea id="footer" class="form-control" @bind="@_footer" rows="3" maxlength="4000"></textarea>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Section>
|
||||||
}
|
}
|
||||||
</TabPanel>
|
</TabPanel>
|
||||||
<TabPanel Name="Permissions" Heading="Permissions" ResourceKey="Permissions">
|
<TabPanel Name="Permissions" Heading="Permissions" ResourceKey="Permissions">
|
||||||
@ -144,6 +161,8 @@
|
|||||||
private string _pane;
|
private string _pane;
|
||||||
private string _containerType;
|
private string _containerType;
|
||||||
private string _allPages = "false";
|
private string _allPages = "false";
|
||||||
|
private string _header = "";
|
||||||
|
private string _footer = "";
|
||||||
private string _permissionNames = "";
|
private string _permissionNames = "";
|
||||||
private List<Permission> _permissions = null;
|
private List<Permission> _permissions = null;
|
||||||
private string _pageId;
|
private string _pageId;
|
||||||
@ -167,37 +186,47 @@
|
|||||||
protected override async Task OnInitializedAsync()
|
protected override async Task OnInitializedAsync()
|
||||||
{
|
{
|
||||||
SetModuleTitle(Localizer["ModuleSettings.Title"]);
|
SetModuleTitle(Localizer["ModuleSettings.Title"]);
|
||||||
|
|
||||||
_title = ModuleState.Title;
|
|
||||||
_moduleSettingsTitle = Localizer["ModuleSettings.Heading"];
|
_moduleSettingsTitle = Localizer["ModuleSettings.Heading"];
|
||||||
_pane = ModuleState.Pane;
|
|
||||||
_containers = ThemeService.GetContainerControls(PageState.Site.Themes, PageState.Page.ThemeType);
|
_containers = ThemeService.GetContainerControls(PageState.Site.Themes, PageState.Page.ThemeType);
|
||||||
_containerType = ModuleState.ContainerType;
|
|
||||||
_allPages = ModuleState.AllPages.ToString();
|
|
||||||
_permissions = ModuleState.PermissionList;
|
|
||||||
_pageId = ModuleState.PageId.ToString();
|
|
||||||
createdby = ModuleState.CreatedBy;
|
|
||||||
createdon = ModuleState.CreatedOn;
|
|
||||||
modifiedby = ModuleState.ModifiedBy;
|
|
||||||
modifiedon = ModuleState.ModifiedOn;
|
|
||||||
_effectivedate = Utilities.UtcAsLocalDate(ModuleState.EffectiveDate);
|
|
||||||
_expirydate = Utilities.UtcAsLocalDate(ModuleState.ExpiryDate);
|
|
||||||
_pages = await PageService.GetPagesAsync(PageState.Site.SiteId);
|
_pages = await PageService.GetPagesAsync(PageState.Site.SiteId);
|
||||||
|
|
||||||
if (ModuleState.ModuleDefinition != null)
|
var pagemodule = await PageModuleService.GetPageModuleAsync(ModuleState.PageModuleId);
|
||||||
{
|
|
||||||
_module = ModuleState.ModuleDefinition.Name;
|
|
||||||
_permissionNames = ModuleState.ModuleDefinition?.PermissionNames;
|
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(ModuleState.ModuleDefinition.SettingsType))
|
_pageId = pagemodule.PageId.ToString();
|
||||||
|
_title = pagemodule.Title;
|
||||||
|
_pane = pagemodule.Pane;
|
||||||
|
_containerType = pagemodule.ContainerType;
|
||||||
|
if (string.IsNullOrEmpty(_containerType))
|
||||||
|
{
|
||||||
|
_containerType = (!string.IsNullOrEmpty(PageState.Page.DefaultContainerType)) ? PageState.Page.DefaultContainerType : PageState.Site.DefaultContainerType;
|
||||||
|
}
|
||||||
|
_header = pagemodule.Header;
|
||||||
|
_footer = pagemodule.Footer;
|
||||||
|
_effectivedate = Utilities.UtcAsLocalDate(pagemodule.EffectiveDate);
|
||||||
|
_expirydate = Utilities.UtcAsLocalDate(pagemodule.ExpiryDate);
|
||||||
|
|
||||||
|
_allPages = pagemodule.Module.AllPages.ToString();
|
||||||
|
createdby = pagemodule.Module.CreatedBy;
|
||||||
|
createdon = pagemodule.Module.CreatedOn;
|
||||||
|
modifiedby = pagemodule.Module.ModifiedBy;
|
||||||
|
modifiedon = pagemodule.Module.ModifiedOn;
|
||||||
|
_permissions = pagemodule.Module.PermissionList;
|
||||||
|
|
||||||
|
if (pagemodule.Module.ModuleDefinition != null)
|
||||||
|
{
|
||||||
|
_module = pagemodule.Module.ModuleDefinition.Name;
|
||||||
|
_permissionNames = pagemodule.Module.ModuleDefinition?.PermissionNames;
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(pagemodule.Module.ModuleDefinition.SettingsType))
|
||||||
{
|
{
|
||||||
// module settings type explicitly declared in IModule interface
|
// module settings type explicitly declared in IModule interface
|
||||||
_moduleSettingsType = Type.GetType(ModuleState.ModuleDefinition.SettingsType);
|
_moduleSettingsType = Type.GetType(pagemodule.Module.ModuleDefinition.SettingsType);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// legacy support - module settings type determined by convention ( ie. existence of a "Settings.razor" component in module )
|
// 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);
|
_moduleSettingsType = Type.GetType(pagemodule.Module.ModuleDefinition.ControlTypeTemplate.Replace(Constants.ActionToken, PageState.Action), false, true);
|
||||||
}
|
}
|
||||||
if (_moduleSettingsType != null)
|
if (_moduleSettingsType != null)
|
||||||
{
|
{
|
||||||
@ -218,7 +247,7 @@
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
AddModuleMessage(string.Format(Localizer["Error.Module.Load"], ModuleState.ModuleDefinitionName), MessageType.Error);
|
AddModuleMessage(string.Format(Localizer["Error.Module.Load"], pagemodule.Module.ModuleDefinitionName), MessageType.Error);
|
||||||
}
|
}
|
||||||
|
|
||||||
var theme = PageState.Site.Themes.FirstOrDefault(item => item.Containers.Any(themecontrol => themecontrol.TypeName.Equals(_containerType)));
|
var theme = PageState.Site.Themes.FirstOrDefault(item => item.Containers.Any(themecontrol => themecontrol.TypeName.Equals(_containerType)));
|
||||||
@ -270,10 +299,12 @@
|
|||||||
{
|
{
|
||||||
pagemodule.ContainerType = string.Empty;
|
pagemodule.ContainerType = string.Empty;
|
||||||
}
|
}
|
||||||
|
pagemodule.Header = _header;
|
||||||
|
pagemodule.Footer = _footer;
|
||||||
await PageModuleService.UpdatePageModuleAsync(pagemodule);
|
await PageModuleService.UpdatePageModuleAsync(pagemodule);
|
||||||
await PageModuleService.UpdatePageModuleOrderAsync(pagemodule.PageId, pagemodule.Pane);
|
await PageModuleService.UpdatePageModuleOrderAsync(pagemodule.PageId, pagemodule.Pane);
|
||||||
|
|
||||||
var module = ModuleState;
|
var module = await ModuleService.GetModuleAsync(ModuleState.ModuleId);
|
||||||
module.AllPages = bool.Parse(_allPages);
|
module.AllPages = bool.Parse(_allPages);
|
||||||
module.PageModuleId = ModuleState.PageModuleId;
|
module.PageModuleId = ModuleState.PageModuleId;
|
||||||
module.PermissionList = _permissionGrid.GetPermissionList();
|
module.PermissionList = _permissionGrid.GetPermissionList();
|
||||||
|
@ -189,4 +189,19 @@
|
|||||||
<data name="ModuleSettings.Title" xml:space="preserve">
|
<data name="ModuleSettings.Title" xml:space="preserve">
|
||||||
<value>Module Settings</value>
|
<value>Module Settings</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="Header.Text" xml:space="preserve">
|
||||||
|
<value>Header:</value>
|
||||||
|
</data>
|
||||||
|
<data name="Header.HelpText" xml:space="preserve">
|
||||||
|
<value>Optionally provide content to be injected above the module instance</value>
|
||||||
|
</data>
|
||||||
|
<data name="Footer.Text" xml:space="preserve">
|
||||||
|
<value>Footer:</value>
|
||||||
|
</data>
|
||||||
|
<data name="Footer.HelpText" xml:space="preserve">
|
||||||
|
<value>Optionally provide content to be injected below the module instance</value>
|
||||||
|
</data>
|
||||||
|
<data name="ModuleContent.Heading" xml:space="preserve">
|
||||||
|
<value>Content</value>
|
||||||
|
</data>
|
||||||
</root>
|
</root>
|
@ -1,6 +1,7 @@
|
|||||||
@namespace Oqtane.UI
|
@namespace Oqtane.UI
|
||||||
@inject SiteState SiteState
|
@inject SiteState SiteState
|
||||||
|
|
||||||
|
@((MarkupString)ModuleState.Header)
|
||||||
@if (_comment != null)
|
@if (_comment != null)
|
||||||
{
|
{
|
||||||
@((MarkupString)_comment)
|
@((MarkupString)_comment)
|
||||||
@ -13,6 +14,7 @@
|
|||||||
<RenderModeBoundary ModuleState="@ModuleState" PageState="@PageState" SiteState="@SiteState" @rendermode="InteractiveRenderMode.GetInteractiveRenderMode(PageState.Site.Runtime, _prerender)" />
|
<RenderModeBoundary ModuleState="@ModuleState" PageState="@PageState" SiteState="@SiteState" @rendermode="InteractiveRenderMode.GetInteractiveRenderMode(PageState.Site.Runtime, _prerender)" />
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@((MarkupString)ModuleState.Footer)
|
||||||
|
|
||||||
@code {
|
@code {
|
||||||
[CascadingParameter]
|
[CascadingParameter]
|
||||||
@ -23,6 +25,8 @@
|
|||||||
|
|
||||||
private bool _prerender;
|
private bool _prerender;
|
||||||
private string _comment;
|
private string _comment;
|
||||||
|
private string _header;
|
||||||
|
private string _footer;
|
||||||
|
|
||||||
protected override void OnParametersSet()
|
protected override void OnParametersSet()
|
||||||
{
|
{
|
||||||
@ -39,11 +43,16 @@
|
|||||||
}
|
}
|
||||||
_comment += " -->";
|
_comment += " -->";
|
||||||
|
|
||||||
|
_header = ModuleState.Header;
|
||||||
|
_footer = ModuleState.Footer;
|
||||||
|
|
||||||
if (PageState.RenderMode == RenderModes.Static && ModuleState.RenderMode == RenderModes.Interactive)
|
if (PageState.RenderMode == RenderModes.Static && ModuleState.RenderMode == RenderModes.Interactive)
|
||||||
{
|
{
|
||||||
// trim PageState to mitigate page bloat caused by Blazor serializing/encrypting state when crossing render mode boundaries
|
// trim PageState to mitigate page bloat caused by Blazor serializing/encrypting state when crossing render mode boundaries
|
||||||
// please note that this performance optimization results in the PageState.Pages property not being available for use in Interactive components
|
// please note that this performance optimization results in the PageState.Pages property not being available for use in Interactive components
|
||||||
PageState.Site.Pages = new List<Page>();
|
PageState.Site.Pages = new List<Page>();
|
||||||
|
ModuleState.Header = string.Empty;
|
||||||
|
ModuleState.Footer = string.Empty;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -76,6 +76,8 @@ namespace Oqtane.Controllers
|
|||||||
module.ContainerType = pagemodule.ContainerType;
|
module.ContainerType = pagemodule.ContainerType;
|
||||||
module.EffectiveDate = pagemodule.EffectiveDate;
|
module.EffectiveDate = pagemodule.EffectiveDate;
|
||||||
module.ExpiryDate = pagemodule.ExpiryDate;
|
module.ExpiryDate = pagemodule.ExpiryDate;
|
||||||
|
module.Header = pagemodule.Header;
|
||||||
|
module.Footer = pagemodule.Footer;
|
||||||
|
|
||||||
module.ModuleDefinition = _moduleDefinitions.FilterModuleDefinition(moduledefinitions.Find(item => item.ModuleDefinitionName == module.ModuleDefinitionName));
|
module.ModuleDefinition = _moduleDefinitions.FilterModuleDefinition(moduledefinitions.Find(item => item.ModuleDefinitionName == module.ModuleDefinitionName));
|
||||||
|
|
||||||
|
@ -246,6 +246,10 @@ namespace Oqtane.Controllers
|
|||||||
pagemodule.Pane = pm.Pane;
|
pagemodule.Pane = pm.Pane;
|
||||||
pagemodule.Order = pm.Order;
|
pagemodule.Order = pm.Order;
|
||||||
pagemodule.ContainerType = pm.ContainerType;
|
pagemodule.ContainerType = pm.ContainerType;
|
||||||
|
pagemodule.EffectiveDate = pm.EffectiveDate;
|
||||||
|
pagemodule.ExpiryDate = pm.ExpiryDate;
|
||||||
|
pagemodule.Header = pm.Header;
|
||||||
|
pagemodule.Footer = pm.Footer;
|
||||||
|
|
||||||
_pageModules.AddPageModule(pagemodule);
|
_pageModules.AddPageModule(pagemodule);
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,29 @@
|
|||||||
|
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
using Oqtane.Databases.Interfaces;
|
||||||
|
using Oqtane.Migrations.EntityBuilders;
|
||||||
|
using Oqtane.Repository;
|
||||||
|
|
||||||
|
namespace Oqtane.Migrations.Tenant
|
||||||
|
{
|
||||||
|
[DbContext(typeof(TenantDBContext))]
|
||||||
|
[Migration("Tenant.06.01.03.02")]
|
||||||
|
public class AddModuleHeaderFooter : MultiDatabaseMigration
|
||||||
|
{
|
||||||
|
public AddModuleHeaderFooter(IDatabase database) : base(database)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void Up(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
var pageModuleEntityBuilder = new PageModuleEntityBuilder(migrationBuilder, ActiveDatabase);
|
||||||
|
pageModuleEntityBuilder.AddMaxStringColumn("Header", true);
|
||||||
|
pageModuleEntityBuilder.AddMaxStringColumn("Footer", true);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void Down(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
// not implemented
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -442,6 +442,8 @@ namespace Oqtane.Repository
|
|||||||
pageModule.Pane = (string.IsNullOrEmpty(pageTemplateModule.Pane)) ? PaneNames.Default : pageTemplateModule.Pane;
|
pageModule.Pane = (string.IsNullOrEmpty(pageTemplateModule.Pane)) ? PaneNames.Default : pageTemplateModule.Pane;
|
||||||
pageModule.Order = (pageTemplateModule.Order == 0) ? 1 : pageTemplateModule.Order;
|
pageModule.Order = (pageTemplateModule.Order == 0) ? 1 : pageTemplateModule.Order;
|
||||||
pageModule.ContainerType = pageTemplateModule.ContainerType;
|
pageModule.ContainerType = pageTemplateModule.ContainerType;
|
||||||
|
pageModule.Header = pageTemplateModule.Header;
|
||||||
|
pageModule.Footer = pageTemplateModule.Footer;
|
||||||
pageModule.IsDeleted = pageTemplateModule.IsDeleted;
|
pageModule.IsDeleted = pageTemplateModule.IsDeleted;
|
||||||
pageModule.Module.PermissionList = new List<Permission>();
|
pageModule.Module.PermissionList = new List<Permission>();
|
||||||
foreach (var permission in pageTemplateModule.PermissionList)
|
foreach (var permission in pageTemplateModule.PermissionList)
|
||||||
|
@ -285,6 +285,8 @@ namespace Oqtane.Services
|
|||||||
ContainerType = pagemodule.ContainerType,
|
ContainerType = pagemodule.ContainerType,
|
||||||
EffectiveDate = pagemodule.EffectiveDate,
|
EffectiveDate = pagemodule.EffectiveDate,
|
||||||
ExpiryDate = pagemodule.ExpiryDate,
|
ExpiryDate = pagemodule.ExpiryDate,
|
||||||
|
Header = pagemodule.Header,
|
||||||
|
Footer = pagemodule.Footer,
|
||||||
|
|
||||||
ModuleDefinition = _moduleDefinitions.FilterModuleDefinition(moduledefinitions.Find(item => item.ModuleDefinitionName == pagemodule.Module.ModuleDefinitionName)),
|
ModuleDefinition = _moduleDefinitions.FilterModuleDefinition(moduledefinitions.Find(item => item.ModuleDefinitionName == pagemodule.Module.ModuleDefinitionName)),
|
||||||
|
|
||||||
|
@ -113,6 +113,18 @@ namespace Oqtane.Models
|
|||||||
[NotMapped]
|
[NotMapped]
|
||||||
public DateTime? ExpiryDate { get; set; }
|
public DateTime? ExpiryDate { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Header content to include at the top of a module instance in the UI
|
||||||
|
/// </summary>
|
||||||
|
[NotMapped]
|
||||||
|
public string Header { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Footer content to include below a module instance in the UI
|
||||||
|
/// </summary>
|
||||||
|
[NotMapped]
|
||||||
|
public string Footer { get; set; }
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region SiteRouter properties
|
#region SiteRouter properties
|
||||||
@ -218,6 +230,8 @@ namespace Oqtane.Models
|
|||||||
ContainerType = ContainerType,
|
ContainerType = ContainerType,
|
||||||
EffectiveDate = EffectiveDate,
|
EffectiveDate = EffectiveDate,
|
||||||
ExpiryDate = ExpiryDate,
|
ExpiryDate = ExpiryDate,
|
||||||
|
Header = Header,
|
||||||
|
Footer = Footer,
|
||||||
CreatedBy = CreatedBy,
|
CreatedBy = CreatedBy,
|
||||||
CreatedOn = CreatedOn,
|
CreatedOn = CreatedOn,
|
||||||
ModifiedBy = ModifiedBy,
|
ModifiedBy = ModifiedBy,
|
||||||
|
@ -41,14 +41,27 @@ namespace Oqtane.Models
|
|||||||
/// Reference to a Razor Container which wraps this module instance.
|
/// Reference to a Razor Container which wraps this module instance.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string ContainerType { get; set; }
|
public string ContainerType { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Start of when this assignment is valid. See also <see cref="ExpiryDate"/>
|
/// Start of when this assignment is valid. See also <see cref="ExpiryDate"/>
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public DateTime? EffectiveDate { get; set; }
|
public DateTime? EffectiveDate { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// End of when this assignment is valid. See also <see cref="EffectiveDate"/>
|
/// End of when this assignment is valid. See also <see cref="EffectiveDate"/>
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public DateTime? ExpiryDate { get; set; }
|
public DateTime? ExpiryDate { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Header content to include above the module instance in the UI
|
||||||
|
/// </summary>
|
||||||
|
public string Header { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Footer content to include below the module instance in the UI
|
||||||
|
/// </summary>
|
||||||
|
public string Footer { get; set; }
|
||||||
|
|
||||||
#region IDeletable Properties
|
#region IDeletable Properties
|
||||||
|
|
||||||
public string DeletedBy { get; set; }
|
public string DeletedBy { get; set; }
|
||||||
|
@ -95,6 +95,8 @@ namespace Oqtane.Models
|
|||||||
Pane = PaneNames.Default;
|
Pane = PaneNames.Default;
|
||||||
Order = 1;
|
Order = 1;
|
||||||
ContainerType = "";
|
ContainerType = "";
|
||||||
|
Header = "";
|
||||||
|
Footer = "";
|
||||||
IsDeleted = false;
|
IsDeleted = false;
|
||||||
PermissionList = new List<Permission>()
|
PermissionList = new List<Permission>()
|
||||||
{
|
{
|
||||||
@ -110,6 +112,8 @@ namespace Oqtane.Models
|
|||||||
public string Pane { get; set; }
|
public string Pane { get; set; }
|
||||||
public int Order { get; set; }
|
public int Order { get; set; }
|
||||||
public string ContainerType { get; set; }
|
public string ContainerType { get; set; }
|
||||||
|
public string Header { get; set; }
|
||||||
|
public string Footer { get; set; }
|
||||||
public bool IsDeleted { get; set; }
|
public bool IsDeleted { get; set; }
|
||||||
public List<Permission> PermissionList { get; set; }
|
public List<Permission> PermissionList { get; set; }
|
||||||
public List<Setting> Settings { get; set; }
|
public List<Setting> Settings { get; set; }
|
||||||
|
Loading…
x
Reference in New Issue
Block a user