provide an indicator in Module Settings when a module is shared across multiple pages

This commit is contained in:
sbwalker
2026-02-25 11:44:15 -05:00
parent 0cc1b5a3e9
commit 573a914699
6 changed files with 30 additions and 18 deletions

View File

@@ -73,27 +73,29 @@
</div> </div>
</div> </div>
<div class="row mb-1 align-items-center"> <div class="row mb-1 align-items-center">
<Label Class="col-sm-3" For="page" HelpText="The page that the module is located on" ResourceKey="Page">Page: </Label> <Label Class="col-sm-3" For="page" HelpText="The page that the module is located on. Please note that shared modules cannot be moved to other pages." ResourceKey="Page">Page: </Label>
<div class="col-sm-9"> <div class="col-sm-9">
<select id="page" class="form-select" @bind="@_pageId" required> @if (PageState.Page.UserId != null || _isShared)
@if (PageState.Page.UserId != null) {
{ <select id="page" class="form-select" @bind="@_pageId" required disabled>
<option value="@PageState.Page.PageId">@(PageState.Page.Name)</option> <option value="@PageState.Page.PageId">@(PageState.Page.Name)</option>
} </select>
else }
else
{
<select id="page" class="form-select" @bind="@_pageId" required>
@if (_pages != null)
{ {
if (_pages != null) foreach (Page p in _pages)
{ {
foreach (Page p in _pages) if (UserSecurity.IsAuthorized(PageState.User, PermissionNames.Edit, p.PermissionList))
{ {
if (UserSecurity.IsAuthorized(PageState.User, PermissionNames.Edit, p.PermissionList)) <option value="@p.PageId">@(new string('-', p.Level * 2))@(p.Name)</option>
{
<option value="@p.PageId">@(new string('-', p.Level * 2))@(p.Name)</option>
}
} }
} }
} }
</select> </select>
}
</div> </div>
</div> </div>
</div> </div>
@@ -161,6 +163,7 @@
private string _pane; private string _pane;
private string _containerType; private string _containerType;
private string _allPages = "false"; private string _allPages = "false";
private bool _isShared = false;
private string _header = ""; private string _header = "";
private string _footer = ""; private string _footer = "";
private string _permissionNames = ""; private string _permissionNames = "";
@@ -207,6 +210,7 @@
_expirydate = Utilities.UtcAsLocalDate(pagemodule.ExpiryDate); _expirydate = Utilities.UtcAsLocalDate(pagemodule.ExpiryDate);
_allPages = pagemodule.Module.AllPages.ToString(); _allPages = pagemodule.Module.AllPages.ToString();
_isShared = pagemodule.Module.IsShared;
createdby = pagemodule.Module.CreatedBy; createdby = pagemodule.Module.CreatedBy;
createdon = pagemodule.Module.CreatedOn; createdon = pagemodule.Module.CreatedOn;
modifiedby = pagemodule.Module.ModifiedBy; modifiedby = pagemodule.Module.ModifiedBy;

View File

@@ -526,7 +526,7 @@
</select> </select>
</div> </div>
</div> </div>
@if (_primary == "False" && (_groupType == SiteGroupTypes.Synchronization || _groupType == SiteGroupTypes.ChangeDetection)) @if (_primary == "False" && !string.IsNullOrEmpty(_synchronized) && (_groupType == SiteGroupTypes.Synchronization || _groupType == SiteGroupTypes.ChangeDetection))
{ {
<div class="row mb-1 align-items-center"> <div class="row mb-1 align-items-center">
<Label Class="col-sm-3" For="synchronized" HelpText="The date/time when the site was last synchronized" ResourceKey="Synchronized">Synchronized: </Label> <Label Class="col-sm-3" For="synchronized" HelpText="The date/time when the site was last synchronized" ResourceKey="Synchronized">Synchronized: </Label>

View File

@@ -130,7 +130,7 @@
<value>Indicate if this module should be displayed on all pages</value> <value>Indicate if this module should be displayed on all pages</value>
</data> </data>
<data name="Page.HelpText" xml:space="preserve"> <data name="Page.HelpText" xml:space="preserve">
<value>The page that the module is located on</value> <value>The page that the module is located on. Please note that shared modules cannot be moved to other pages.</value>
</data> </data>
<data name="Title.Text" xml:space="preserve"> <data name="Title.Text" xml:space="preserve">
<value>Title: </value> <value>Title: </value>

View File

@@ -617,6 +617,7 @@ namespace Oqtane.Infrastructure
private string SynchronizeModules(IServiceProvider provider, ISettingRepository settingRepository, IPageModuleRepository pageModuleRepository, IModuleRepository moduleRepository, SiteGroupMember siteGroupMember, List<PageModule> primaryPageModules, List<PageModule> secondaryPageModules, Page primaryPage, Page secondaryPage, int secondarySiteId) private string SynchronizeModules(IServiceProvider provider, ISettingRepository settingRepository, IPageModuleRepository pageModuleRepository, IModuleRepository moduleRepository, SiteGroupMember siteGroupMember, List<PageModule> primaryPageModules, List<PageModule> secondaryPageModules, Page primaryPage, Page secondaryPage, int secondarySiteId)
{ {
var log = ""; var log = "";
var removePageModules = secondaryPageModules.Where(item => item.PageId == secondaryPage.PageId).ToList();
// iterate through primary modules on primary page // iterate through primary modules on primary page
foreach (var primaryPageModule in primaryPageModules.Where(item => item.PageId == primaryPage.PageId)) foreach (var primaryPageModule in primaryPageModules.Where(item => item.PageId == primaryPage.PageId))
@@ -651,7 +652,7 @@ namespace Oqtane.Infrastructure
if (pageModule == null) if (pageModule == null)
{ {
// check if module exists // check if module exists in site (ie. a shared instance)
var module = secondaryPageModules.FirstOrDefault(item => item.Module.ModuleDefinitionName == primaryPageModule.Module.ModuleDefinitionName && item.Title.ToLower() == primaryPageModule.Title.ToLower())?.Module; var module = secondaryPageModules.FirstOrDefault(item => item.Module.ModuleDefinitionName == primaryPageModule.Module.ModuleDefinitionName && item.Title.ToLower() == primaryPageModule.Title.ToLower())?.Module;
if (module == null) if (module == null)
{ {
@@ -685,7 +686,7 @@ namespace Oqtane.Infrastructure
if (pageModule != null) if (pageModule != null)
{ {
secondaryPageModules.Remove(pageModule); removePageModules.Remove(pageModule);
} }
// module settings // module settings
@@ -716,7 +717,7 @@ namespace Oqtane.Infrastructure
if (siteGroupMember.SiteGroup.Type == SiteGroupTypes.Synchronization) if (siteGroupMember.SiteGroup.Type == SiteGroupTypes.Synchronization)
{ {
// remove modules on the secondary page which do not exist on the primary page // remove modules on the secondary page which do not exist on the primary page
foreach (var secondaryPageModule in secondaryPageModules.Where(item => item.PageId == secondaryPage.PageId)) foreach (var secondaryPageModule in removePageModules)
{ {
pageModuleRepository.DeletePageModule(secondaryPageModule.PageModuleId); pageModuleRepository.DeletePageModule(secondaryPageModule.PageModuleId);
log += Log(siteGroupMember, $"Module Instance Deleted: {secondaryPageModule.Title} - {CreateLink(siteGroupMember.AliasName + "/" + secondaryPageModule.Page.Path)}"); log += Log(siteGroupMember, $"Module Instance Deleted: {secondaryPageModule.Title} - {CreateLink(siteGroupMember.AliasName + "/" + secondaryPageModule.Page.Path)}");

View File

@@ -1,5 +1,6 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Security.Policy;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using Oqtane.Models; using Oqtane.Models;
using Oqtane.Shared; using Oqtane.Shared;
@@ -98,6 +99,7 @@ namespace Oqtane.Repository
var permissions = _permissions.GetPermissions(pagemodule.Module.SiteId, EntityNames.Module).ToList(); var permissions = _permissions.GetPermissions(pagemodule.Module.SiteId, EntityNames.Module).ToList();
pagemodule = GetPageModule(pagemodule, moduledefinitions, permissions); pagemodule = GetPageModule(pagemodule, moduledefinitions, permissions);
} }
pagemodule.Module.IsShared = db.PageModule.Count(item => item.ModuleId == pagemodule.ModuleId) > 1;
return pagemodule; return pagemodule;
} }

View File

@@ -33,6 +33,11 @@ namespace Oqtane.Models
/// </summary> /// </summary>
public bool AllPages { get; set; } public bool AllPages { get; set; }
/// <summary>
/// indicates if the module is shared across multiple pages (only set in specific scenarios to ensure performance)
/// </summary>
[NotMapped]
public bool IsShared { get; set; }
/// <summary> /// <summary>
/// Reference to the <see cref="ModuleDefinition"/> used for this module. /// Reference to the <see cref="ModuleDefinition"/> used for this module.