performance optimizations in site router and remove dependency between page and module in route specification
This commit is contained in:
@ -17,15 +17,15 @@
|
||||
}
|
||||
}
|
||||
</div>
|
||||
<br />
|
||||
<br />
|
||||
|
||||
@code {
|
||||
public override SecurityAccessLevel SecurityAccessLevel { get { return SecurityAccessLevel.Admin; } }
|
||||
|
||||
List<Page> pages;
|
||||
|
||||
protected override void OnInitialized()
|
||||
{
|
||||
// display list of pages which are children of current page
|
||||
pages = PageState.Pages.Where(item => item.ParentId == PageState.Page.PageId).ToList();
|
||||
Page admin = PageState.Pages.Where(item => item.Path == "admin").FirstOrDefault();
|
||||
pages = PageState.Pages.Where(item => item.ParentId == admin.PageId).ToList();
|
||||
}
|
||||
}
|
||||
|
@ -30,13 +30,14 @@
|
||||
{
|
||||
ShowProgressIndicator();
|
||||
|
||||
if (await FileService.UploadFilesAsync(PageState.Site.SiteRootPath, files, ""))
|
||||
string result = await FileService.UploadFilesAsync(PageState.Site.SiteRootPath, files, "");
|
||||
if (result == "")
|
||||
{
|
||||
AddModuleMessage("Files Uploaded Successfully", MessageType.Success);
|
||||
}
|
||||
else
|
||||
{
|
||||
AddModuleMessage("Upload Failed", MessageType.Error);
|
||||
AddModuleMessage("Upload Failed For " + result.Replace(",",", ") + ". This Could Be Due To A Network Error Or Because A File Type Is Restricted.", MessageType.Error);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
|
@ -9,7 +9,7 @@
|
||||
}
|
||||
else
|
||||
{
|
||||
<ActionLink Action="Add" Text="Add File" Style="float: right; margin: 10px;" />
|
||||
<ActionLink Action="Add" Text="Add Files" Style="float: right; margin: 10px;" />
|
||||
|
||||
<Pager Items="@Files">
|
||||
<Header>
|
||||
|
@ -74,7 +74,8 @@
|
||||
{
|
||||
try
|
||||
{
|
||||
if (await FileService.UploadFilesAsync("Modules", files, ""))
|
||||
string result = await FileService.UploadFilesAsync("Modules", files, "");
|
||||
if (result == "")
|
||||
{
|
||||
AddModuleMessage("Module Uploaded Successfully. Click Install To Complete Installation.", MessageType.Success);
|
||||
uploaded = true;
|
||||
@ -82,7 +83,7 @@
|
||||
}
|
||||
else
|
||||
{
|
||||
AddModuleMessage("Module Upload Failed.", MessageType.Error);
|
||||
AddModuleMessage("Upload Failed For " + result.Replace(",",", ") + ". This Could Be Due To A Network Error Or Because A File Type Is Restricted.", MessageType.Error);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
|
@ -73,7 +73,8 @@
|
||||
{
|
||||
try
|
||||
{
|
||||
if (await FileService.UploadFilesAsync("Themes", files, ""))
|
||||
string result = await FileService.UploadFilesAsync("Themes", files, "");
|
||||
if (result == "")
|
||||
{
|
||||
AddModuleMessage("Theme Uploaded Successfully. Click Install To Complete Installation.", MessageType.Success);
|
||||
uploaded = true;
|
||||
@ -81,7 +82,7 @@
|
||||
}
|
||||
else
|
||||
{
|
||||
AddModuleMessage("Theme Upload Failed.", MessageType.Error);
|
||||
AddModuleMessage("Upload Failed For " + result.Replace(",",", ") + ". This Could Be Due To A Network Error Or Because A File Type Is Restricted.", MessageType.Error);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
|
@ -62,7 +62,8 @@ else
|
||||
{
|
||||
try
|
||||
{
|
||||
if (await FileService.UploadFilesAsync("Framework", files, ""))
|
||||
string result = await FileService.UploadFilesAsync("Framework", files, "");
|
||||
if (result == "")
|
||||
{
|
||||
AddModuleMessage("Framework Uploaded Successfully. Click Upgrade To Complete Installation.", MessageType.Success);
|
||||
uploaded = true;
|
||||
@ -70,7 +71,7 @@ else
|
||||
}
|
||||
else
|
||||
{
|
||||
AddModuleMessage("Framework Upload Failed.", MessageType.Error);
|
||||
AddModuleMessage("Upload Failed For " + result.Replace(",",", ") + ". This Could Be Due To A Network Error Or Because A File Type Is Restricted.", MessageType.Error);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
|
@ -6,13 +6,13 @@
|
||||
@inject HttpClient http
|
||||
@inject SiteState sitestate
|
||||
|
||||
<table class="form-group">
|
||||
<table class="table table-borderless">
|
||||
<tr>
|
||||
<td>
|
||||
<label for="Name" class="control-label">Content: </label>
|
||||
</td>
|
||||
<td>
|
||||
<textarea class="form-control" @bind="@content" rows="5" style="width:400px;" />
|
||||
<textarea class="form-control" @bind="@content" rows="5" />
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
@ -33,17 +33,20 @@ namespace Oqtane.Services
|
||||
return await http.GetJsonAsync<List<string>>(apiurl + "?folder=" + Folder);
|
||||
}
|
||||
|
||||
public async Task<bool> UploadFilesAsync(string Folder, string[] Files, string FileUploadName)
|
||||
public async Task<string> UploadFilesAsync(string Folder, string[] Files, string FileUploadName)
|
||||
{
|
||||
bool success = false;
|
||||
string result = "";
|
||||
|
||||
var interop = new Interop(jsRuntime);
|
||||
await interop.UploadFiles(apiurl + "/upload", Folder, FileUploadName);
|
||||
|
||||
// uploading files is asynchronous so we need to wait for the upload to complete
|
||||
bool success = false;
|
||||
int attempts = 0;
|
||||
while (attempts < 5 && success == false)
|
||||
{
|
||||
Thread.Sleep(2000); // wait 2 seconds
|
||||
result = "";
|
||||
|
||||
List<string> files = await GetFilesAsync(Folder);
|
||||
if (files.Count > 0)
|
||||
@ -54,13 +57,18 @@ namespace Oqtane.Services
|
||||
if (!files.Contains(file))
|
||||
{
|
||||
success = false;
|
||||
result += file + ",";
|
||||
}
|
||||
}
|
||||
}
|
||||
attempts += 1;
|
||||
}
|
||||
if (!success)
|
||||
{
|
||||
result = result.Substring(0, result.Length - 1);
|
||||
}
|
||||
|
||||
return success;
|
||||
return result;
|
||||
}
|
||||
|
||||
public async Task DeleteFileAsync(string Folder, string File)
|
||||
|
@ -7,7 +7,7 @@ namespace Oqtane.Services
|
||||
public interface IFileService
|
||||
{
|
||||
Task<List<string>> GetFilesAsync(string Folder);
|
||||
Task<bool> UploadFilesAsync(string Folder, string[] Files, string FileUploadName);
|
||||
Task<string> UploadFilesAsync(string Folder, string[] Files, string FileUploadName);
|
||||
Task DeleteFileAsync(string Folder, string File);
|
||||
}
|
||||
}
|
||||
|
@ -6,8 +6,7 @@ namespace Oqtane.Services
|
||||
{
|
||||
public interface IModuleService
|
||||
{
|
||||
Task<List<Module>> GetModulesAsync(int PageId);
|
||||
Task<List<Module>> GetModulesAsync(int SiteId, string ModuleDefinitionName);
|
||||
Task<List<Module>> GetModulesAsync(int SiteId);
|
||||
Task<Module> GetModuleAsync(int ModuleId);
|
||||
Task<Module> AddModuleAsync(Module Module);
|
||||
Task<Module> UpdateModuleAsync(Module Module);
|
||||
|
@ -26,21 +26,15 @@ namespace Oqtane.Services
|
||||
get { return CreateApiUrl(sitestate.Alias, NavigationManager.Uri, "Module"); }
|
||||
}
|
||||
|
||||
public async Task<List<Module>> GetModulesAsync(int PageId)
|
||||
public async Task<List<Module>> GetModulesAsync(int SiteId)
|
||||
{
|
||||
List<Module> modules = await http.GetJsonAsync<List<Module>>(apiurl + "?pageid=" + PageId.ToString());
|
||||
List<Module> modules = await http.GetJsonAsync<List<Module>>(apiurl + "?siteid=" + SiteId.ToString());
|
||||
modules = modules
|
||||
.OrderBy(item => item.Order)
|
||||
.ToList();
|
||||
return modules;
|
||||
}
|
||||
|
||||
public async Task<List<Module>> GetModulesAsync(int SiteId, string ModuleDefinitionName)
|
||||
{
|
||||
List<Module> modules = await http.GetJsonAsync<List<Module>>(apiurl + "?siteid=" + SiteId.ToString() + "&moduledefinitionname=" + ModuleDefinitionName);
|
||||
return modules.ToList();
|
||||
}
|
||||
|
||||
public async Task<Module> GetModuleAsync(int ModuleId)
|
||||
{
|
||||
return await http.GetJsonAsync<Module>(apiurl + "/" + ModuleId.ToString());
|
||||
|
@ -117,7 +117,7 @@
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (Module module in PageState.Modules.Where(item => item.Pane.ToLower() == Name.ToLower() && !item.IsDeleted).OrderBy(x => x.Order).ToArray())
|
||||
foreach (Module module in PageState.Modules.Where(item => item.PageId == PageState.Page.PageId && item.Pane.ToLower() == Name.ToLower() && !item.IsDeleted).OrderBy(x => x.Order).ToArray())
|
||||
{
|
||||
// check if user is authorized to view module
|
||||
if (UserSecurity.IsAuthorized(PageState.User, "View", module.Permissions))
|
||||
|
@ -159,18 +159,18 @@
|
||||
// extract admin route elements from path
|
||||
string[] segments = path.Split(new[] { '/' }, StringSplitOptions.RemoveEmptyEntries);
|
||||
int result;
|
||||
// check if path has moduleid and control specification ie. page/moduleid/control/
|
||||
if (segments.Length >= 2 && int.TryParse(segments[segments.Length - 2], out result))
|
||||
{
|
||||
// path has moduleid and control specification ie. page/moduleid/control/
|
||||
control = segments[segments.Length - 1];
|
||||
moduleid = result;
|
||||
path = path.Replace(moduleid.ToString() + "/" + control + "/", "");
|
||||
}
|
||||
else
|
||||
{
|
||||
if (segments.Length >= 2 && int.TryParse(segments[segments.Length - 2], out result))
|
||||
// check if path has only moduleid specification ie. page/moduleid/
|
||||
if (segments.Length >= 1 && int.TryParse(segments[segments.Length - 1], out result))
|
||||
{
|
||||
// path has only moduleid specification ie. page/moduleid/
|
||||
moduleid = result;
|
||||
path = path.Replace(moduleid.ToString() + "/", "");
|
||||
}
|
||||
@ -244,8 +244,8 @@
|
||||
|
||||
if (PageState == null || reload >= Reload.Page)
|
||||
{
|
||||
modules = await ModuleService.GetModulesAsync(page.PageId);
|
||||
modules = ProcessModules(modules, moduledefinitions, pagestate.Control, page.Panes, site);
|
||||
modules = await ModuleService.GetModulesAsync(site.SiteId);
|
||||
modules = ProcessModules(modules, moduledefinitions, page.PageId, pagestate.ModuleId, pagestate.Control, page.Panes, site.DefaultContainerType);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -341,15 +341,9 @@
|
||||
return page;
|
||||
}
|
||||
|
||||
private List<Module> ProcessModules(List<Module> modules, List<ModuleDefinition> moduledefinitions, string control, string panes, Site site)
|
||||
private List<Module> ProcessModules(List<Module> modules, List<ModuleDefinition> moduledefinitions, int pageid, int moduleid, string control, string panes, string defaultcontainertype)
|
||||
{
|
||||
ModuleDefinition moduledefinition;
|
||||
|
||||
if (control == "")
|
||||
{
|
||||
control = Constants.DefaultControl;
|
||||
}
|
||||
|
||||
Dictionary<string, int> paneindex = new Dictionary<string, int>();
|
||||
foreach (Module module in modules)
|
||||
{
|
||||
@ -358,62 +352,80 @@
|
||||
if (moduledefinition != null)
|
||||
{
|
||||
string typename = moduledefinition.ControlTypeTemplate;
|
||||
if (moduledefinition.ControlTypeRoutes != "")
|
||||
if (module.ModuleId == moduleid && control != "")
|
||||
{
|
||||
foreach (string route in moduledefinition.ControlTypeRoutes.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries))
|
||||
// check if the module defines custom routes
|
||||
if (moduledefinition.ControlTypeRoutes != "")
|
||||
{
|
||||
if (route.StartsWith(control + "="))
|
||||
foreach (string route in moduledefinition.ControlTypeRoutes.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries))
|
||||
{
|
||||
typename = route.Replace(control + "=", "");
|
||||
if (route.StartsWith(control + "="))
|
||||
{
|
||||
typename = route.Replace(control + "=", "");
|
||||
}
|
||||
}
|
||||
}
|
||||
module.ModuleType = typename.Replace("{Control}", control);
|
||||
|
||||
// admin controls need to load additional metadata from the IModuleControl interface
|
||||
if (moduleid == module.ModuleId)
|
||||
{
|
||||
typename = module.ModuleType;
|
||||
// check for core module actions component
|
||||
if (Constants.DefaultModuleActions.Contains(control))
|
||||
{
|
||||
typename = Constants.DefaultModuleActionsTemplate.Replace("{Control}", control);
|
||||
}
|
||||
Type moduletype = Type.GetType(typename);
|
||||
if (moduletype != null)
|
||||
{
|
||||
var moduleobject = Activator.CreateInstance(moduletype);
|
||||
module.SecurityAccessLevel = (SecurityAccessLevel)moduletype.GetProperty("SecurityAccessLevel").GetValue(moduleobject, null);
|
||||
module.ControlTitle = (string)moduletype.GetProperty("Title").GetValue(moduleobject);
|
||||
module.Actions = (string)moduletype.GetProperty("Actions").GetValue(moduleobject);
|
||||
module.UseAdminContainer = (bool)moduletype.GetProperty("UseAdminContainer").GetValue(moduleobject);
|
||||
}
|
||||
}
|
||||
}
|
||||
module.ModuleType = typename.Replace("{Control}", control);
|
||||
|
||||
// get IModuleControl properties
|
||||
typename = module.ModuleType;
|
||||
// check for core module actions component
|
||||
if (Constants.DefaultModuleActions.Contains(control))
|
||||
else
|
||||
{
|
||||
typename = Constants.DefaultModuleActionsTemplate.Replace("{Control}", control);
|
||||
module.ModuleType = typename.Replace("{Control}", Constants.DefaultControl);
|
||||
}
|
||||
Type moduletype = Type.GetType(typename);
|
||||
if (moduletype != null)
|
||||
|
||||
}
|
||||
|
||||
if (module.PageId == pageid)
|
||||
{
|
||||
// ensure module's pane exists in current page and if not, assign it to the Admin pane
|
||||
if (!panes.ToLower().Contains(module.Pane.ToLower()))
|
||||
{
|
||||
var moduleobject = Activator.CreateInstance(moduletype);
|
||||
module.SecurityAccessLevel = (SecurityAccessLevel)moduletype.GetProperty("SecurityAccessLevel").GetValue(moduleobject, null);
|
||||
module.ControlTitle = (string)moduletype.GetProperty("Title").GetValue(moduleobject);
|
||||
module.Actions = (string)moduletype.GetProperty("Actions").GetValue(moduleobject);
|
||||
module.UseAdminContainer = (bool)moduletype.GetProperty("UseAdminContainer").GetValue(moduleobject);
|
||||
module.Pane = Constants.AdminPane;
|
||||
}
|
||||
}
|
||||
|
||||
// ensure module's pane exists in current page and if not, assign it to the Admin pane
|
||||
if (!panes.ToLower().Contains(module.Pane.ToLower()))
|
||||
{
|
||||
module.Pane = Constants.AdminPane;
|
||||
// calculate module position within pane
|
||||
if (paneindex.ContainsKey(module.Pane))
|
||||
{
|
||||
paneindex[module.Pane] += 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
paneindex.Add(module.Pane, 0);
|
||||
}
|
||||
module.PaneModuleIndex = paneindex[module.Pane];
|
||||
}
|
||||
|
||||
// calculate module position within pane
|
||||
if (paneindex.ContainsKey(module.Pane))
|
||||
{
|
||||
paneindex[module.Pane] += 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
paneindex.Add(module.Pane, 0);
|
||||
}
|
||||
module.PaneModuleIndex = paneindex[module.Pane];
|
||||
|
||||
if (string.IsNullOrEmpty(module.ContainerType))
|
||||
{
|
||||
module.ContainerType = site.DefaultContainerType;
|
||||
module.ContainerType = defaultcontainertype;
|
||||
}
|
||||
}
|
||||
|
||||
foreach (Module module in modules)
|
||||
{
|
||||
module.PaneModuleCount = paneindex[module.Pane] + 1;
|
||||
if (module.PageId == pageid)
|
||||
{
|
||||
module.PaneModuleCount = paneindex[module.Pane] + 1;
|
||||
}
|
||||
}
|
||||
return modules;
|
||||
}
|
||||
|
@ -152,7 +152,6 @@
|
||||
string moduleid = "";
|
||||
List<Module> modules = new List<Module>();
|
||||
Dictionary<string, string> containers = new Dictionary<string, string>();
|
||||
int pagemanagementmoduleid = -1;
|
||||
string moduledefinitionname = "";
|
||||
string pane = "";
|
||||
string title = "";
|
||||
@ -162,7 +161,7 @@
|
||||
string cardclass = "text-white bg-secondary";
|
||||
string message = "";
|
||||
|
||||
protected override async Task OnParametersSetAsync()
|
||||
protected override void OnParametersSet()
|
||||
{
|
||||
if (!string.IsNullOrEmpty(ButtonClass))
|
||||
{
|
||||
@ -200,11 +199,6 @@
|
||||
pane = panes.Count() == 1 ? panes.SingleOrDefault() : "";
|
||||
containers = ThemeService.GetContainerTypes(PageState.Themes);
|
||||
containertype = PageState.Site.DefaultContainerType;
|
||||
List<Module> modules = await ModuleService.GetModulesAsync(PageState.Site.SiteId, Constants.PageManagementModule);
|
||||
if (modules.Count > 0)
|
||||
{
|
||||
pagemanagementmoduleid = modules.FirstOrDefault().ModuleId;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -223,12 +217,12 @@
|
||||
StateHasChanged();
|
||||
}
|
||||
|
||||
private async Task PageChanged(ChangeEventArgs e)
|
||||
private void PageChanged(ChangeEventArgs e)
|
||||
{
|
||||
string pageid = (string)e.Value;
|
||||
if (pageid != "")
|
||||
{
|
||||
foreach(Module module in await ModuleService.GetModulesAsync(int.Parse(pageid)))
|
||||
foreach(Module module in PageState.Modules.Where(item => item.PageId == int.Parse(pageid)))
|
||||
{
|
||||
if (UserSecurity.IsAuthorized(PageState.User, "View", module.Permissions))
|
||||
{
|
||||
@ -287,27 +281,6 @@
|
||||
}
|
||||
}
|
||||
|
||||
private string PageUrl(string action)
|
||||
{
|
||||
string url = "";
|
||||
if (pagemanagementmoduleid != -1)
|
||||
{
|
||||
switch (action)
|
||||
{
|
||||
case "Add":
|
||||
url = EditUrl("admin/pages", pagemanagementmoduleid, action, "");
|
||||
break;
|
||||
case "Edit":
|
||||
url = EditUrl("admin/pages", pagemanagementmoduleid, action, "id=" + PageState.Page.PageId.ToString());
|
||||
break;
|
||||
case "Delete":
|
||||
url = EditUrl("admin/pages", pagemanagementmoduleid, action, "id=" + PageState.Page.PageId.ToString());
|
||||
break;
|
||||
}
|
||||
}
|
||||
return url;
|
||||
}
|
||||
|
||||
private void EditMode()
|
||||
{
|
||||
if (UserSecurity.IsAuthorized(PageState.User, "Edit", PageState.Page.Permissions))
|
||||
@ -343,15 +316,42 @@
|
||||
private void Navigate(string location)
|
||||
{
|
||||
HideControlPanel();
|
||||
Module module;
|
||||
switch (location)
|
||||
{
|
||||
case "Admin":
|
||||
NavigationManager.NavigateTo(NavigateUrl("admin"));
|
||||
// get admin dashboard moduleid
|
||||
module = PageState.Modules.Where(item => item.ModuleDefinitionName == Constants.AdminDashboardModule).FirstOrDefault();
|
||||
if (module != null)
|
||||
{
|
||||
NavigationManager.NavigateTo(EditUrl(PageState.Page.Path, module.ModuleId, "Index", ""));
|
||||
}
|
||||
break;
|
||||
case "Add":
|
||||
case "Edit":
|
||||
case "Delete":
|
||||
NavigationManager.NavigateTo(PageUrl(location));
|
||||
string url = "";
|
||||
// get page management moduleid
|
||||
module = PageState.Modules.Where(item => item.ModuleDefinitionName == Constants.PageManagementModule).FirstOrDefault();
|
||||
if (module != null)
|
||||
{
|
||||
switch (location)
|
||||
{
|
||||
case "Add":
|
||||
url = EditUrl(PageState.Page.Path, module.ModuleId, location, "");
|
||||
break;
|
||||
case "Edit":
|
||||
url = EditUrl(PageState.Page.Path, module.ModuleId, location, "id=" + PageState.Page.PageId.ToString());
|
||||
break;
|
||||
case "Delete":
|
||||
url = EditUrl(PageState.Page.Path, module.ModuleId, location, "id=" + PageState.Page.PageId.ToString());
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (url != "")
|
||||
{
|
||||
NavigationManager.NavigateTo(url);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user