oqtane.framework/Oqtane.Client/Shared/SiteRouter.razor

350 lines
9.9 KiB
Plaintext

@using System
@using Oqtane.Services
@using Oqtane.Models
@using System.Linq
@using System.Collections.Generic
@using Oqtane.Shared
@using Microsoft.JSInterop
@using Microsoft.AspNetCore.Components.Routing
@inject AuthenticationStateProvider AuthenticationStateProvider
@inject SiteState SiteState
@inject IUriHelper UriHelper
@inject INavigationInterception NavigationInterception
@inject IComponentContext ComponentContext
@inject IJSRuntime jsRuntime
@inject IAliasService AliasService
@inject ITenantService TenantService
@inject ISiteService SiteService
@inject IPageService PageService
@inject IUserService UserService
@inject IModuleService ModuleService
@inject IModuleDefinitionService ModuleDefinitionService
@inject IThemeService ThemeService
@implements IHandleAfterRender
@DynamicComponent
@code {
[CascadingParameter] PageState PageState { get; set; }
[Parameter] Action<PageState> OnStateChange { get; set; }
PageState pagestate;
RenderFragment DynamicComponent { get; set; }
string _absoluteUri;
bool _navigationInterceptionEnabled;
protected override void OnInit()
{
_absoluteUri = UriHelper.GetAbsoluteUri();
UriHelper.OnLocationChanged += OnLocationChanged;
DynamicComponent = builder =>
{
if (pagestate != null)
{
builder.OpenComponent(0, Type.GetType(Constants.DefaultPage));
builder.CloseComponent();
}
};
}
public void Dispose()
{
UriHelper.OnLocationChanged -= OnLocationChanged;
}
protected override async Task OnParametersSetAsync()
{
if (PageState == null)
{
await Refresh();
}
}
private async Task Refresh()
{
List<ModuleDefinition> moduledefinitions;
List<Models.Theme> themes;
List<Alias> aliases;
Alias alias;
Site site;
List<Page> pages;
Page page;
User user;
List<Module> modules;
bool reload = false;
if (PageState == null)
{
aliases = await AliasService.GetAliasesAsync();
alias = null;
}
else
{
aliases = PageState.Aliases;
alias = PageState.Alias;
}
if (alias == null || GetAlias(_absoluteUri, aliases).Name != alias.Name)
{
alias = GetAlias(_absoluteUri, aliases);
SiteState.Alias = alias; // set state for services
reload = true;
}
if (PageState == null || reload == true)
{
moduledefinitions = await ModuleDefinitionService.GetModuleDefinitionsAsync();
themes = await ThemeService.GetThemesAsync();
site = await SiteService.GetSiteAsync(alias.SiteId);
}
else
{
moduledefinitions = PageState.ModuleDefinitions;
themes = PageState.Themes;
site = PageState.Site;
}
if (site != null || reload == true)
{
user = null;
if (PageState == null || reload == true)
{
var authState = await AuthenticationStateProvider.GetAuthenticationStateAsync();
if (authState.User.Identity.IsAuthenticated)
{
user = await UserService.GetCurrentUserAsync();
}
}
else
{
user = PageState.User;
}
string path = new Uri(_absoluteUri).PathAndQuery.Substring(1);
if (path.EndsWith("/")) { path = path.Substring(0, path.Length - 1); }
if (alias.Path != "")
{
path = path.Replace(alias.Path, "");
if (path.StartsWith("/")) { path = path.Substring(1); }
}
Dictionary<string, string> querystring = ParseQueryString(path);
if (querystring.ContainsKey("reload"))
{
reload = true;
}
if (PageState == null || reload == true)
{
pages = await PageService.GetPagesAsync(site.SiteId);
}
else
{
pages = PageState.Pages;
}
if (path.IndexOf("?") != -1)
{
path = path.Substring(0, path.IndexOf("?"));
}
if (PageState == null || reload == true)
{
page = pages.Where(item => item.Path == path).FirstOrDefault();
}
else
{
page = PageState.Page;
}
if (page.Path != path)
{
page = pages.Where(item => item.Path == path).FirstOrDefault();
reload = true;
}
if (page != null)
{
// check if user is authorized to view page
if (UserService.IsAuthorized(user, page.ViewPermissions))
{
pagestate = new PageState();
pagestate.ModuleDefinitions = moduledefinitions;
pagestate.Themes = themes;
pagestate.Aliases = aliases;
pagestate.Alias = alias;
pagestate.Site = site;
pagestate.Pages = pages;
pagestate.Page = page;
pagestate.User = user;
pagestate.Uri = new Uri(_absoluteUri, UriKind.Absolute);
pagestate.QueryString = querystring;
pagestate.ModuleId = -1;
pagestate.Control = "";
if (querystring.ContainsKey("mid"))
{
pagestate.ModuleId = int.Parse(querystring["mid"]);
}
if (querystring.ContainsKey("ctl"))
{
pagestate.Control = querystring["ctl"];
}
if (PageState != null && (PageState.ModuleId != pagestate.ModuleId || PageState.Control != pagestate.Control))
{
reload = true;
}
if (PageState == null || reload == true)
{
modules = await ModuleService.GetModulesAsync(page.PageId);
modules = ProcessModules(modules, moduledefinitions, pagestate.Control, page.Panes);
}
else
{
modules = PageState.Modules;
}
pagestate.Modules = modules;
OnStateChange?.Invoke(pagestate);
}
else
{
// user is not authorized to view page
}
}
else
{
// page does not exist
}
}
else
{
// site does not exist
}
}
private async void OnLocationChanged(object sender, LocationChangedEventArgs args)
{
_absoluteUri = args.Location;
await Refresh();
}
Task IHandleAfterRender.OnAfterRenderAsync()
{
if (!_navigationInterceptionEnabled && ComponentContext.IsConnected)
{
_navigationInterceptionEnabled = true;
return NavigationInterception.EnableNavigationInterceptionAsync();
}
return Task.CompletedTask;
}
private Dictionary<string, string> ParseQueryString(string path)
{
Dictionary<string, string> querystring = new Dictionary<string, string>();
if (path.IndexOf("?") != -1)
{
foreach (string kvp in path.Substring(path.IndexOf("?") + 1).Split('&'))
{
if (kvp != "")
{
if (kvp.Contains("="))
{
string[] pair = kvp.Split('=');
querystring.Add(pair[0], pair[1]);
}
else
{
querystring.Add(kvp, "true"); // default querystring when no value is provided
}
}
}
}
return querystring;
}
private List<Module> ProcessModules(List<Module> modules, List<ModuleDefinition> moduledefinitions, string control, string panes)
{
ModuleDefinition moduledefinition;
if (control == "")
{
control = Constants.DefaultControl;
}
Dictionary<string, int> paneindex = new Dictionary<string, int>();
foreach (Module module in modules)
{
// set the type based on the template and action
moduledefinition = moduledefinitions.Where(item => item.ModuleDefinitionName == module.ModuleDefinitionName).FirstOrDefault();
if (moduledefinition != null)
{
string typename = moduledefinition.ControlTypeTemplate;
if (moduledefinition.ControlTypeRoutes != "")
{
foreach (string route in moduledefinition.ControlTypeRoutes.Split(';'))
{
if (route.StartsWith(control + "="))
{
typename = route.Replace(control + "=", "");
}
}
}
module.ModuleType = typename.Replace("{Control}", control);
}
// ensure module's pane exists in current page and if not, assign it to the Admin pane
if (!panes.Contains(module.Pane))
{
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];
}
foreach (Module module in modules)
{
module.PaneModuleCount = paneindex[module.Pane] + 1;
}
return modules;
}
private Alias GetAlias(string absoluteUri, List<Alias> aliases)
{
string aliasname;
Alias alias = null;
Uri uri = new Uri(absoluteUri);
if (uri.Segments.Count() > 1)
{
// check if first path segment is an alias ( ie. a subfolder - www.domain.com/subfolder )
aliasname = uri.Authority + "/" + uri.Segments[1];
if (aliasname.EndsWith("/")) { aliasname = aliasname.Substring(0, aliasname.Length - 1); }
alias = aliases.Where(item => item.Name == aliasname).FirstOrDefault();
}
if (alias == null)
{
aliasname = uri.Authority;
alias = aliases.Where(item => item.Name == aliasname).FirstOrDefault();
}
if (alias == null && aliases.Count > 0)
{
// use first alias if Uri does not exist
alias = aliases.FirstOrDefault();
}
alias.Scheme = uri.Scheme;
return alias;
}
}